[modern c++] shared_ptr和weak_ptr
原创
©著作权归作者所有:来自51CTO博客作者obentul的原创作品,请联系作者获取转载授权,否则将追究法律责任
shared_ptr
shared_ptr是用来智能管理内存的,shared_ptr的 构造函数,拷贝构造,拷贝赋值 这三个动作都会导致 引用计数的增加,析构函数,移动拷贝,移动赋值 这三个动作都会导致 引用计数的减少。当引用计数为 0 时,指向的资源被释放,但是要记得自行把shared_ptr置空,它不会像QPointer那样进行自动置空动作。
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());
cout << pb.use_count() << endl; //1
cout << pa.use_count() << endl; //1
pb->pa_ = pa;
pa->pb_ = pb;
cout << pb.use_count() << endl; //2
cout << pa.use_count() << endl; //2
}
int main()
{
fun();
return 0;
}
这段代码的输出为:
可以看到 A 和 B的析构都没有被触发。如果把其中一个 shared_ptr 换为 weak_ptr 就可以了,如下:
class B; //声明
class A
{
public:
shared_ptr<B> pb_;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
weak_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
};
void fun()
{
shared_ptr<B> pb(new B());
shared_ptr<A> pa(new A());
cout << pb.use_count() << endl; //1
cout << pa.use_count() << endl; //1
pb->pa_ = pa;
pa->pb_ = pb;
cout << pb.use_count() << endl; //2
cout << pa.use_count() << endl; //1
}
int main()
{
fun();
return 0;
}
上面这段代码输出为:
1
1
2
1 //这里之所以是1,是因为 pb->pa_ = pa; 这个语句是吧 shared_ptr赋值给weak_ptr,因此计数没增加
A delete
B delete
需要注意:weak_ptr没有实现 * 和 -> 的重载实现,因此不能直接当做指针来使用,需要先通过lock() 函数返回一个 shared_ptr ,然后再进行指针操作。