发展
boost::shared_ptr
C++11后
std::shared_ptr
什么是智能指针
智能指针是一个类,该类里封装了普通指针。以shared_ptr为例
为什么引入智能指针
程序员编程时可能会忘记释放申请的空间在函数结束,造成内存泄漏。引入智能指针可以避免这个问题,类会自动调用析构函数,释放内存空间。
智能指针有哪些
C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用。
unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象。
shared_ptr实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放,即引用计数为0时。
weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。
怎样使用智能指针
联想到new的使用方法
int* p=new int; *p=3;
int* p=new int(3);
int* p(new int); *p=3;
int* p(new int(3));
可推导出make_unique的用法
unique_ptr<int> ptr=std::make_unique<int>(); *ptr=3;//先分配内存再初始化
unique_ptr<int> ptr=std::make_unique<int>(3);//
unique_ptr<int> ptr(std::make_unique<int>());*ptr=3;
unique_ptr<int> ptr(std::make_unique<int>(3));
上述unique_ptr<int>均可由auto代替:
auto ptr=std::make_unique<int>(3);
也可使用new方法
unique_ptr<int> ptr(int(3));//此处调用了unique_ptr的类型转换构造函数
分配STL类,底层调用了容器的allocator。故string的三种分配方法都可用上
shared_ptr<string> p1 = make_shared<string>(10, '9');
shared_ptr<string> p2 = make_shared<string>("hello");
shared_ptr<string> p3 = make_shared<string>();
shared_ptr的线程安全问题
多线程读写 shared_ptr 要加锁,用来保证修改引用计数和操作指针一起完成。
考虑一个简单的场景,有 3 个 shared_ptr<Foo> 对象 x、g、n:
shared_ptr<Foo> g(new Foo); // 线程之间共享的 shared_ptr
shared_ptr<Foo> x; // 线程 A 的局部变量
shared_ptr<Foo> n(new Foo); // 线程 B 的局部变量
执行x=g、n=g,可能会发生race condition问题