智能指针作用:
普通指针new以后,有的人忘记删除就会引起内存泄漏,而且删除时也会有一些问题,例如一片内存地址被同时删除多次就会引起程序崩溃。所以这个时候引进了智能指针,可以在离开作用域后自动释放。这里介绍4种智能指针,智能指针包含在头文件#include
1.auto_ptr
它采用所有权模式。允许一个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
2.unique_str
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")); //这种可以
3.shared_ptr
和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; //不会报错
4.weak_ptr
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;
}