本文主要讨论auto_ptr、unique_ptr、shared_ptr这三种智能指针的区别与使用场景。
auto_ptr与unique_ptr:auto_ptr从c++11之后已停止使用,unique_ptr能够再auto_ptr的所有使用条件下运用,且能在编译阶段纠错。相比于auto_ptr,unique_ptr的优势如下:
不会出现重复删除的情况
unique_ptr在一般情况下是不能够作为“=”右边的元素进行赋值操作的,从而防止了对同一个对象重复删除而带来的错误,以下几种情况unique_ptr能够作为赋值号的右值:
1、unique_ptr<srtring>p2 = fun("aa");
unique_ptr<string> fun(string s){
unique_ptr<string> temp(new string(s));
return temp;
}
此时fun函数返回的unique_ptr智能指针,在完成赋值操作后会自动销毁。
2、unique_ptr<string> temp(new string(s));
unique_ptr<srtring>p2=move(temp);
在move操作下,系统会直接讲p2指向temp中的内容,通过让temp不再指向原来的内容,所以就不存在多次delete的情况。
3、unique_ptr<string> temp(new string(s));
shared_ptr<string> p2=temp;
shared_ptr包含一个显示构造函数,可用于讲右值unique_ptr转换为shared_ptr
shared_ptr与unique_ptr:其主要区别在于该智能指针所指向的对象是否可以被多个变量引用
1、当程序要使用多个指向同一个对象的指针,应该选择shared_ptr
2、shared_ptr于unique_ptr使用的时候,都需要用new或new[]去分配内存。
shared_ptr:new
unique_ptr:new、new[]
weak_ptr的存在主要是为了配合shared_ptr使用,防止其出现循环引用
#include <iostream>
#include <memory>
using namespace std;
class A;
class B;
class A {
public:
std::shared_ptr<B> bptr;
~A() {
cout << "A is deleted" << endl; // 析构函数后,才去释放成员变量
}
};
class B {
public:
std::shared_ptr<A> aptr;
~B() {
cout << "B is deleted" << endl; // 析构函数后,才去释放成员变量
}
};
int main()
{
std::shared_ptr<A> pa;
{
std::shared_ptr<A> ap(new A);//ap(1)
std::shared_ptr<B> bp(new B);//bp(1)
ap->bptr = bp;//bp(2)
bp->aptr = ap;//ap(1)
}
return 0;
}
为了防止上述代码种所出现的循环引用问题,c++11中引入了一种不计数的智能制造weak_ptr,其可以shared_ptr进行初始化,然后通过调用lock来获得其指向的shared_ptr的指针。关于reset函数,当其置空的时候,可用于释放指向内容,当前指向其他内容的时候,表明释放先前的,指向后来开辟的内存。weak_ptr指向shared_ptr并不会增加shared_ptr的计数,这样就可以在一定程度上解决循环引用的问题。
下表为智能指针常用的操作函数: