实战c++中的智能指针unique_ptr系列-- unique_ptr的operator=、operator bool、reset、swap、get等介绍

既然打算把unique_ptr写一个系列,就要详尽一点,有些内容也许在vector的时候有个涉及,但是现在还是再谈论一番。

我们要把unique_ptr看做一个类,废话了,它当然是一个类。所以这个类肯定也重载了赋值运算符,即operator=。现在就开始看看operator=在unique_ptr中的使用:

官方描述如下:

move assignment (1)
unique_ptr& operator= (unique_ptr&& x) noexcept;
assign null pointer (2)
unique_ptr& operator= (nullptr_t) noexcept;
type-cast assignment (3)
template <class U, class E>
  unique_ptr& operator= (unique_ptr<U,E>&& x) noexcept;
copy assignment (deleted!) (4)
unique_ptr& operator= (const unique_ptr&) = delete;

这里简要实例:

#include <iostream>
#include <memory>

int main () {
  std::unique_ptr<int> foo;
  std::unique_ptr<int> bar;

  foo = std::unique_ptr<int>(new int (101));  // rvalue

  bar = std::move(foo);                       // using std::move

  std::cout << "foo: ";
  if (foo) std::cout << *foo << ‘\n‘; else std::cout << "empty\n";

  std::cout << "bar: ";
  if (bar) std::cout << *bar << ‘\n‘; else std::cout << "empty\n";

  return 0;
}

输出:

foo: empty

bar: 101

唯一需要说明的就是std::move后,foo变为了empty,如果对于这个empty再做一些操作的话,就会导致一些灾难了。

其实说白了,就是摧毁原来的指针,并把新指针指向原来指针指向的对象。。。。

那么接下来reset方法即出厂了,到达上面的效果:

#include <iostream>
#include <memory>

int main () {
  std::unique_ptr<int> up;  // empty

  up.reset (new int);       // takes ownership of pointer
  *up=5;
  std::cout << *up << ‘\n‘;

  up.reset (new int);       // deletes managed object, acquires new pointer
  *up=10;
  std::cout << *up << ‘\n‘;

  up.reset();               // deletes managed object

  return 0;
}
//输出:
5
10

swap

我们在vector里就接触过,unique_ptr同样具有这个成员函数:

Exchanges the contents of the unique_ptr object with those of x, transferring ownership of any managed object between them without destroying either.

最重要的就是没有销毁任何一个:

#include <iostream>
#include <memory>

int main () {
  std::unique_ptr<int> foo (new int(10));
  std::unique_ptr<int> bar (new int(20));

  foo.swap(bar);

  std::cout << "foo: " << *foo << ‘\n‘;
  std::cout << "bar: " << *bar << ‘\n‘;

  return 0;
}
//输出
foo为20
bar为10

get

get很简单,唯一需要注意的就是:

Notice that a call to this function does not make unique_ptr release ownership of the pointer (i.e., it is still responsible for deleting the managed data at some point). Therefore, the value returned by this function shall not be used to construct a new managed pointer.

最主要的一点就是,智能指针没有释放,即没有失去所有权:

#include <iostream>
#include <memory>

int main () {
                                           // foo   bar    p
                                           // ---   ---   ---
  std::unique_ptr<int> foo;                // null
  std::unique_ptr<int> bar;                // null  null
  int* p = nullptr;                        // null  null  null

  foo = std::unique_ptr<int>(new int(10)); // (10)  null  null
  bar = std::move(foo);                    // null  (10)  null
  p = bar.get();                           // null  (10)  (10)
  *p = 20;                                 // null  (20)  (20)
  p = nullptr;                             // null  (20)  null

  foo = std::unique_ptr<int>(new int(30)); // (30)  (20)  null
  p = foo.release();                       // null  (20)  (30)
  *p = 40;                                 // null  (20)  (40)

  std::cout << "foo: ";
  if (foo) std::cout << *foo << ‘\n‘; else std::cout << "(null)\n";

  std::cout << "bar: ";
  if (bar) std::cout << *bar << ‘\n‘; else std::cout << "(null)\n";

  std::cout << "p: ";
  if (p) std::cout << *p << ‘\n‘; else std::cout << "(null)\n";
  std::cout << ‘\n‘;

  delete p;   // the program is now responsible of deleting the object pointed to by p
              // bar deletes its managed object automatically

  return 0;
}

即上面代码提到的,p = bar.get(); 后,bar并非被释放,也就相当于指针p和智能指针bar共同管理一个对象,所以就*p做的一切,都会反应到bar指向的对象上。

这段代码有了一个与get相对比的方法:release

release

不必多说:

This call does not destroy the managed object, but the unique_ptr object is released from the responsibility of deleting the object. Some other entity must take responsibility for deleting the object at some point.

重点就是一句话:智能指针被释放。

#include <iostream>
#include <memory>

int main () {
  std::unique_ptr<int> auto_pointer (new int);
  int * manual_pointer;

  *auto_pointer=10;

  manual_pointer = auto_pointer.release();
  // (auto_pointer is now empty)

  std::cout << "manual_pointer points to " << *manual_pointer << ‘\n‘;

  delete manual_pointer;

  return 0;
}

最后了,再介绍一个operator bool吧,即unique_ptr有这样一个成员函数,来检查是否为空:

#include <iostream>
#include <memory>

int main () {
  std::unique_ptr<int> foo;
  std::unique_ptr<int> bar (new int(12));

  if (foo) std::cout << "foo points to " << *foo << ‘\n‘;
  else std::cout << "foo is empty\n";

  if (bar) std::cout << "bar points to " << *bar << ‘\n‘;
  else std::cout << "bar is empty\n";

  return 0;
}
时间: 2024-08-24 09:37:01

实战c++中的智能指针unique_ptr系列-- unique_ptr的operator=、operator bool、reset、swap、get等介绍的相关文章

实战c++中的智能指针unique_ptr系列-- 使用std::unique_ptr代替new operator(错误:‘unique_ptr’ is not a member of ‘std’)

写了很多篇关于vector的博客,其实vector很便捷,也很简单.但是很多易错的问题都是vector中的元素为智能指针所引起的.所以决定开始写一写关于智能指针的故事,尤其是unique_ptr指针的故事. 这是个开始,就让我们使用std::unique_ptr代替new operator吧! 还是用程序说话: #include<iostream> int main() { while (true) int *x = new int; } 看下任务管理器中的内存: 此时使用智能指针unique

实战c++中的智能指针unique_ptr系列-- unique_ptr与lambda的错误结合(尤其是捕获lambda中的unique_ptr)

lambda表达式是C++11新引入的东西,给我们带来了很多的方便,使得代码简洁明了. 但是当我们把unique_ptr和lambda表达式结合的时候,错误就往往会出现,而且是致命的. 直接看看下面的代码: #include "stdafx.h" #include <memory> #include <vector> #include <algorithm> class Message { public: Message() {} }; int ma

实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)

unique_ptr的成员函数在上一篇博客中几乎全部涵盖,其实还有一个很有踢掉,即std::unique_ptr::get_deleter 字面已经很明显了,就获得deleter: Returns the stored deleter The stored deleter is a callable object. A functional call to this object with a single argument of member type pointer is expected

COCOS2D-X中的智能指针

Cocos2d-x中所有内存管理方式的基础是引用计数,动态分配一个Ref对象后其引用计数为1,并通过retain和release来增持和减少其引用计数.引用计数本身并不能帮助我们进行内存管理. 为了正确地释放对象的内存,Cocos2d-x使用Objective-C里面的自动回收池的机制来管理对象内存的释放.Autorelease有点类似于一个共享的"智能指针",该"智能指针"的作用域为一帧,该帧结束后,它将释放自己的引用计数,此时,如果该对象没有被其他"共

C++中的智能指针

众所周知.C++中对堆内存的申请与释放全然由用户来控制,这就造成用户在使用的时候常常造成内存泄漏.野指针.反复释放等常见的挂掉问题,所以我们有必要提供一套机制.使得用户仅仅需申请对应的内存,不用管释放的问题,事实上这属于著名的RAII(Resource Acquisition Is Initialization)技术 .在C++中这样的技术称作"智能指针",C++中的智能指针技术越来越受到广泛应用.以下简要介绍下智能指针. 从以上描写叙述中能够看出,我们须要提供一套内存显式申请与隐式释

Android系统篇之----Android中的智能指针

一.前言 今天我们开启Android系统篇的文章了,其实一直想弄,只是之前一直没有太多深入的了解,最近又把这块拿出来好好看了一下,所以想从新梳理一下,来看看Android中的这块知识,首先我们今天来看一下:Android中的智能指针的概念,为什么说先看一下智能指针这个知识呢?因为我们在看Android源码的时候,会发现几乎好多地方都用到了这个东东,所以我们在介绍后面的知识点,先来看看这个吧. 二.问题 那么Android中的智能指针是个什么东西呢?我们知道Android用的Java语言开发的,J

Boost中的智能指针(转)

这篇文章主要介绍 boost中的智能指针的使用.(转自:http://www.cnblogs.com/sld666666/archive/2010/12/16/1908265.html) 内存管理是一个比较繁琐的问题,C++中有两个实现方案: 垃圾回收机制和智能指针.垃圾回收机制因为性能等原因不被C++的大佬们推崇, 而智能指针被认为是解决C++内存问题的最优方案. 1. 定义 一个智能指针就是一个C++的对象, 这对象的行为像一个指针,但是它却可以在其不需要的时候自动删除.注意这个“其不需要的

OSG中的智能指针

在OpenSceneGraph中,智能指针(Smart pointer)的概念指的是一种类的模板,它针对某一特定类型的对象(即Referenced类及其派生类)构建,提供了自己的管理模式,以避免因为用户使用new运算符创建对象实例之后,没有及时用delete运算符释放对象,而造成部分内存空间被浪费的后果,也就是所谓的内存泄露错误. 由于OSG中与场景图形有关的大多数类均派生自Referenced类,因此OSG大量使用了智能指针来实现场景图形节点的管理.智能指针的使用为用户提供了一种自动内存释放的

ATL和vc++中的智能指针(分别是CComPtr和_com_ptr_t)

一.智能指针的概念 智能指针是一个类,不是指针,智能指针在所包含的指针不再被使用时候会自动释放该所包含指针所占用的系统资源,而不用手动释放. 原理:智能指针封装了包含指针的AddRef()函数和Release()函数,且在该类不被需要的时候在析构函数里调用包含指针的Release()函数释放包含指针的资源.因此实质是利用类的析构达到调用包含指针的Release()函数的目的. 二.VC++中的智能指针:_com_ptr_t _com_ptr_t实质是一个类模板.使用它时需要提供三个参数:接口的名