智能指针
智能指针 保证能够做到资源的自动释放
利用栈上的对象出作用域自动析构的特征,来做到自动释放的
分为两种:不带引用计数的智能指针和带引用计数的智能指针
1、不带引用计数的智能指针
auto_ptr
不推荐使用,当拷贝构造或者赋值时,指针所有权会转移
scoped_ptr
只能使用单个构造
源码中:
scoped_ptr(const scoped_ptr<T>&)=delete;
scoped_ptr<T>& operator=(const scoped_ptr<T>&)=delete;
推荐使用 unique_ptr
源码中unique_ptr和scoped_ptr一样,拷贝构造函数和重载负责函数被删除
unique_ptr(const unique_ptr<T>&)=delete;
unique_ptr<T>& operator=(const unique_ptr<T>&)=delete;
但存在右值引用的拷贝构造函数和重载负责函数
unique_ptr(const unique_ptr<T>&& src);
unique_ptr<T>& operator=(const unique_ptr<T>&& src);
eg:
unique_ptr<int> p1(new int);
unique_ptr<int> p2(std::move(p1));
使用move将p1强制转换为右值,调用右值拷贝构造函数
之后p1管理的资源已提交给p2,p1内的指针为null
2、带引用计数的智能指针
shared_ptr 强智能指针 可以改变资源的引用计数
weak_ptr 弱智能指针 不会改变资源的引用计数
当智能指针的引用计数为0时,该指针指向的资源才被释放
shared_ptr的交叉引用问题
交叉引用是什么问题?什么结果?怎么解决?
#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:
A(){cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
weak_ptr<B> _ptrb;
};
class B{
public:
B(){cout<<"B()"<<endl;}
~B(){cout<<"~B()"<<endl;}
weak_ptr<A> _ptra;
};
int main(int argc,char** argv)
{
shared_ptr<A> p1(new A);
shared_ptr<B> p2(new B);
/*
p1->_ptrb=p2;
p2->_ptra=p1;
*/
return 0;
}
上面成员构造和析构正常,但是若去掉注释,运行结果是只有构造,没有析构,造成内存泄露!
故应该:定义对象的地方使用强智能指针 引用对象的地方使用弱智能指针
防止出现交叉引用
注意:
weak_ptr 没有提供 * 和 ->
若使用资源则需要需要转换为强智能指针
shared_ptr<A> ps=_ptra.lock();
if(ps!=nullptr) //防止ptra指针指向的资源在其他线程中被释放
{
}