C++ 98的 std::auto_ptr已经被彻底遗弃了,取而代之的是unique_ptr、shared_ptr与weak_ptr。大部分时候我们自己手动申请内存方式内存都是没有问题的,问题是如果程序很大了之后,一个复杂的对象,多次拷贝的代价非常高,很多地方都会使用到,只存在一份拷贝显然是最好的,这个时候对象生命周期的管理就会很复杂,所以c++引入了智能指针。
任何事物都会有两面性。
Shared_ptr
摘录于Effective C++, 3rd Edition, Item 17: 在 standalone statements(独立语句)中将 new 出来的 objects(对象)存入 smart pointers(智能指针)
1 | class Widget { |
processWidget运行的过程应该是
New Widget
shared_ptr constructor
Priority()
我在llvm上测试的结果也是这个执行顺序
也许某些编译器上可能执行的顺序是
New Widget
Priority() //发生异常
- shared_ptr constructor
就有可能有内存泄露
所以最好的办法还是应该把new widget提到外面来写,所以好的编码习惯很重要。
循环引用
1 | #include <iostream> |
要解决这个问题就需要引入一个弱引用的智能指针了weak_ptr
1 | class A; |
这两种指针其实和oc里面的 strong, weak非常相识。
weak_ptr的另外一种用法
使用情景:当类对象被 shared_ptr 管理时,需要在类自己定义的函数里把当前类对象作为参数传给其他函数时,这时需要传递一个 shared_ptr ,否则就不能保持 shared_ptr 管理这个类对象的语义(因为有一个 raw pointer 指向这个类对象,而 shared_ptr 对类对象的这个引用没有计数,很有可能 shared_ptr 已经把类对象资源释放了,而那个调用函数还在使用类对象——显然,这肯定会产生错误)。《摘录:http://blog.csdn.net/zhongguoren666/article/details/8617436》
直接看官网的例子吧:
《http://en.cppreference.com/w/cpp/memory/enable_shared_from_this》
1 | #include <memory> |
- 绝对不能在构造函数中调用shared_from_this()
因为shared_ptr里面初始化enable_shared_from_this的成员weak_ptr, 这个时候weak_ptr还是空值。
- 为什么内部不能用this指针
因为我们程序中用shared_ptr来管理指针,如果我们在类的内部传递的过程中用原始指针,这样类内部的引用shared_ptr不会察觉到,因为有可能我们传进去的时候已经被shared_ptr释放掉了
unique_ptr
相对就要单纯许多了,unique_ptr“唯一”拥有其所指对象,只能有一个unique_ptr指向给定对象(通过禁止拷贝语义、只有移动语义来实现)。
代替普通指针
1 | void foo() |
在函数中返回对象
1 | unique_ptr<X> foo() |
放入容器中
1 | vector<unique_ptr<string>> vs { new string{“1111”}, new string{“2222”},new string{“3333”} }; |
支持直接持有数组
1 | std::shared_ptr<int> p(new int[10], |