C++11学习笔记之6——智能指针

auto_ptr

auto_ptr是基于copy语义的智能指针,它实现了operator=运算,这样隐晦的拥有权转移也导致了它被C++11遗弃。考虑下面的代码:

1
2
3
4
5
auto_ptr<int> smartPtr1( new int);
{
auto_ptr<int> smartPtr2= smartPtr1;
}
int *ptr = smartPtr1.get(); // get NULL pointer here

原有的smartPtr1已经将所有权以这种隐式copy语义传递出去,而对程序猿来说这样很容易引起误操作。

unique_ptr

unique_ptr是用来替代auto_ptr的新的智能指针,它使用的是move语义,必须由程序猿明确地使用std::move来指定指针所有权的转移。
unique_ptr中拷贝构造函数和赋值运算都被声明为private:

1
2
3
private:
unique_ptr(const _Myt&amp;); // not defined
operator=(const _Myt&amp;); // not defined

维基百科上的例子很简单,拿来

1
2
3
4
5
6
std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; // 编译会出错
std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.

p3.reset(); //释放内存.
p1.reset(); //实际上什么都没做.

要使用新的unique_ptr也很简单,直接由查找/替换所有的auto_ptr即可。

shared_ptr and weak_ptr

shard_ptr使用引用计数,多个shared_ptr可以共享一个指针,只有最后一个shared_ptr销毁时才释放内存,但是又有循环计数的问题出现,因此引入weak_ptr,只引用,不计数,如果一块内存被shared_ptr和weak_ptr同时引用, 当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存, 内存也会被释放. 所以weak_ptr不保证它指向的内存一定是有效的, 在使用之前需要检查.