普通指针new以后,有的人忘记删除就会引起内存泄漏,而且删除时也会有一些问题,例如一片内存地址被同时删除多次就会引起程序崩溃。所以这个时候引进了智能指针,可以在离开作用域后自动释放。这里介绍4种智能指针,智能指针包含在头文件#include
它采用所有权模式。允许一个auto_ptr类型变量赋给另一个auto_ptr,程序不会报错,但是有些问题,代码如下
auto_ptr<int>p1(new int(1)); auto_ptr<int>p2; p2 = p1; //auto_ptr不会报错,此时不能访问p1,只能访问p2 cout << *p1; cout << *p2;会引起内存崩溃问题,所以在c++11中取消了auto_ptr
c++11及以后都用这个,因为程序不允许一个unique_ptr类型变量赋给另一个unique_ptr,可以防止内存崩溃。
unique_ptr<int> p1(new int(1)); unique_ptr<int> p2; p2 = p1; //报错但是如果给unique_ptr类型赋一个消亡值则无所谓
unique_ptr<string> p3; p3 = unique_ptr<string>(new string ("test")); //这种可以 和auto_ptr是相对的,shared_ptr是所有权模式,而shared_ptr则是共享模式,多个对象可以访问同一片区域,它使用计数机制来表明资源被几个指针共享,通过成员函数use_count()来查看资源的所有者个数当我们调用release()时,当前指针会释放资源所有权,计数减一。当计数等于0时,资源会被释放。
shared_ptr<string>p1(new string("test")); shared_ptr<string>p2; p2 = p1; cout << *p2 << " " << *p1; //不会报错 weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放,weak_ptr不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它
class B; class A { public: shared_ptr<B> pb_; ~A() { cout << "A delete\n"; } }; class B { public: shared_ptr<A> pa_; ~B() { cout << "B delete\n"; } }; void fun() { shared_ptr<B> pb(new B()); shared_ptr<A> pa(new A()); pb->pa_ = pa; pa->pb_ = pb; cout << pb.use_count() << endl; cout << pa.use_count() << endl; } int main() { fun(); //两个shared_ptr相互引用所以资源引用计数为2,跳出函数只减1,资源引用计数不为0,就不会调用析构函数 return 0; }为了解决shared_ptr死锁问题把其中一个shared_ptr换成weak_ptr就行了
class B; class A { public: weak_ptr<B> pb_; ~A() { cout << "A delete\n"; } }; class B { public: shared_ptr<A> pa_; ~B() { cout << "B delete\n"; } }; void fun() { shared_ptr<B> pb(new B()); shared_ptr<A> pa(new A()); pb->pa_ = pa; pa->pb_ = pb; cout << pb.use_count() << endl; cout << pa.use_count() << endl; } int main() { fun(); //两个shared_ptr相互引用所以资源引用计数为2,跳出函数只减1,资源引用计数不为0,就不会调用析构函数,用了weak_ptr以后资源引用计数不会增加也不会减少,只和shared_ptr有关 return 0; }weak_ptr有点难理解推荐一篇大佬博客:https://blog.csdn.net/albertsh/article/details/82286999