解决shared_ptr的循环引用
创作时间:
作者:
@小白创作中心
解决shared_ptr的循环引用
引用
CSDN
1.
https://blog.csdn.net/guaiguaiyalj/article/details/143248681
在实现智能指针shared_ptr中有一个问题就是循环引用的问题,对于循环引用看下面的图来理解:
node1和node2两个智能指针对象指向两个节点,引用计数变成1,我们不需要手动delete。node1的_next指向node2,node2的_prev指向node1,引用计数变成2(因为我们定义的结构中_next和_prev也是shared_ptr的智能指针对象)。node1和node2析构,引用计数减1,但是_next还指向下一个节点。_prev还指向上 一个节点。- 也就是说
_next析构了,node2的引用计数变为0,就释放了;同理_prev析构了,node1就释放了。 - 但是
_next属于node1的成员,node1释放了,_next才会析构,而node1由_prev管理,_prev属于node2成员,所以这就叫循环引用,谁也不会释放。
再换个角度理解:
假如这里只有一个指向:node1->_next = node2;这样node1的计数为1,node2的计数为2,node1和node2析构就会让node1的计数见减为0,node2减为1,然后node1计数为0释放,同时也会让node1的成员_next析构,_next的析构就会导致node2的计数减为0,这样node2也会释放,就不会有循环引用的问题。
我们这次要解决循环引用,就要把结构体中的_next和_prev不要计数就可以解决,那样node1和node2析构时资源也就释放了。解决方案:在引用计数的场景下,把节点中的_prev和_next改成weak_ptr就可以了。原理就是,node1->_next = node2和node2->_prev = node1时,weak_ptr的_next和 _prev不会增加node1和node2的引用计数。
template<class T>
class weak_ptr
{
public:
weak_ptr()
:_ptr(nullptr)
{}
weak_ptr(const shared_ptr<T>& sp)
:_ptr(sp.get())
{}
weak_ptr<T>& operator=(const shared_ptr<T>& sp)
{
_ptr = sp.get();
return *this;
}
// 像指针一样
T& operator*(){return *_ptr;}
T* operator->(){return _ptr;}
private:
T* _ptr;
};
这里拷贝构造和赋值都是对shared_ptr对象,也就是说只需要拷贝构造和赋值shared_ptr对象的_ptr就可以了。因为这是不同的类,_ptr是shared_ptr中的私有成员,不可访问,有两种方式可以实现:1、友元类;2、在shared_ptr中写一个公有的成员函数get来获取_ptr。
热门推荐
小学语文教学:如何有效培养语言文字运用能力?
语文课堂里的心理滋养:以《乌鸦喝水》为例
新高考改革背景下,如何高效学好语文?
韶关樱花季,二月打卡必选!
南华寺:禅宗祖庭的历史密码
古人的蛇崇拜:中国蛇神众多!南美信奉羽蛇神,埃及则独爱眼镜蛇
蛇!比龙更早的华夏信仰,已有8000年历史
秦始皇求仙地:秦皇岛的千年传奇
阿那亚礼堂:秦皇岛最文艺的网红打卡地
吃高麗菜顧胃?認識胃潰瘍的成因、症狀、飲食,3大營養素保護胃壁!
春节必备:开口笑的甜蜜祝福
心理学家的恋爱秘籍:用科学方法经营完美感情
《爱情公寓》中的恋爱心理学:如何提升感情幸福感
《如何让你爱的人爱上你》:45个科学方法助你找到理想伴侣
良师无国界:中国教练丁其庆在日本羽坛的30年
李祉默:《群星闪耀时》里的“小戏骨”,用演技征服观众
李祉默演绎《群星闪耀时》,网友热议:小孩姐太可爱!
年夜饭必备:这道菜寓意年年有余!
ABO世界观下的特殊词汇大揭秘!
从《邪恶力量》到主流文化:ABO设定的崛起与争议
网络直播:重塑社交方式的新力量
李佳琦直播间背后的五大心理需求揭秘
《将人生哲学到底》:十位哲学家的思想如何助你走出生活困境
打麻将成解压神器,重拾生活信心!
为何富裕家庭热衷让孩子投身体育?运动六大好处助力孩子全面发展
广州年夜饭必备:发财就手的做法大揭秘!
年夜饭必备:腊肉香肠大比拼!
年夜饭食材安全选购指南:从选购到储存的全方位攻略
去张家界的交通方式有哪些?如何选择合适的出行方式?
中老年人群常见疾病:腔梗!做好早期预防