shared_ptr循环引用问题:https://blog.youkuaiyun.com/yc2zgh1314/article/details/51264963
#include <iostream>
#include <thread>
#include<vector>
#include<string>
#include<queue>
#include<mutex>
#include<unordered_map>
#include<unordered_set>
#include<memory>
using namespace std;
void test1() {
shared_ptr<int> p(new int(5));
shared_ptr<int> q(p);
shared_ptr<int> r(q);
cout << p.use_count() << q.use_count() << r.use_count() << endl;//3 3 3
cout << *p << *q << *r << endl;//5 5 5
*p = 1; //修改共享int的值
cout << *p << *q << *r << endl;//1 1 1 (一个共享对象改了所有都改)
p.reset();
cout << p.use_count() << q.use_count() << r.use_count() << endl;//0 2 2(p本身被析构,计数变为0,其他的共享对象计数-1)
}
void test2() {
shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);
cout << p.use_count() << q.use_count() << endl;//1 1(弱引用不增加计数)
q.reset();
cout << p.use_count() << q.use_count() << endl; //1 0(弱引用析构了也不影响shared_ptr)
}
void test3() {
shared_ptr<int> p(new int(5));
//shared_ptr<int> r(p);//如果增加这句话,下面会打印shared_ptr<int> r
weak_ptr<int> q(p);
p.reset();
/*
lock成员获取到的shared_ptr p指针创建一个临时对象(我们weak_ptr弱引用的体现),
这个临时对象同样指向p,即使p执了reset这样的delete引用的操作,弱引用对象仍然持有改智能指针的地址,
直到r指针的生命周期结束才会释放
*/
if (shared_ptr<int> r = q.lock())
{
cout << "shared_ptr<int> r";
}
else {
cout << "shared_ptr<int> p析构了" << endl;//执行这句话!
}
}
void test4() {
// p 和 q 都调用了 shared_ptr 的构造函数,该构造方式使得 p 和 q
// 都开辟了自已的引用资源对象 _Ref_count_base,即 _Ref_count_base 有两个,
// 都记录了 A 对象的引用计数为 1,析构时 ptr1 和 ptr2 的引用计数各自减为 1,导致 A 对象析构两次,出现逻辑错误。
int *a = new int(0);
shared_ptr<int> p(a);
shared_ptr<int> q(a);
cout << p.use_count() << q.use_count() << endl;//1 1
//shared_ptr<int> q(p);//上上行这样写就没有问题,调用的是shared_ptr的拷贝构造函数
}
int main() {
test4();
//if (int* r = q.get())
//{
// // use *r
// ;
//}
return 0;
}
muduo库中关于enable_shared_from_this:
shared_ptr<A> getSharedPtr()
{
return shared_ptr<A>(this);
}
根据test4明白了 shared_ptr 构造函数和拷贝构造函数的做的事情不同后,就能理解当需要返回一个需要 shared_ptr 管理的对象为什么不能写成 return shared_ptr< A >(this) 了。因为这样会调用 shared_ptr 的构造函数,对于 this 对象再创建一个新的引用计数对象,从而导致对象多次析构而出现逻辑错误。
智能指针相关参考公众号:https://mp.weixin.qq.com/s/kee5m2qJ4sLPEKIc-lMf-Q