C++中的轮回引用
固然C++11引入了智能指针的,可是开拓职员在与内存的斗争题目上并没有解放,假如我门适用不妥如故有内存走漏题目,个中智能指针的轮回引用缺陷是最大的题目。 // // main.cpp // test // // Created by 杜国超 on 17/9/9. // Copyright © 2017年 杜国超. All rights reserved. // #include <iostream> #include <memory> #include <vector> using namespace std; class CObjB; class CObjA { public: CObjA() { cout << "CObjA Constructor..." << endl; } ~CObjA() { cout << "CObjA Destructor..." << endl; } shared_ptr<CObjB> m_pb; // 在A中引用B }; class CObjB { public: CObjB() { cout << "CObjB Constructor..." << endl; } ~CObjB() { cout << "CObjB Destructor..." << endl; } shared_ptr<CObjA> m_pa; // 在B中引用A }; int main() { shared_ptr<CObjA> tmpPa = make_shared<CObjA>(); shared_ptr<CObjB> tmpPb = make_shared<CObjB>(); tmpPa->m_pb = tmpPb; tmpPb->m_pa = tmpPa; std::cout << "CObjA referencr num:" << tmpPa.use_count() << endl; std::cout << "CObjB referencr num:" << tmpPb.use_count() << endl; // tmpPa->m_pb.reset(); // tmpPb->m_pa.reset(); // std::cout << "CObjA referencr num:" << tmpPa.use_count() << endl; // std::cout << "CObjB referencr num:" << tmpPb.use_count() << endl; } 我们可以看到在出main函数浸染域之前两个指针指向的内存并没有开释(指针指向的工具没有挪用析构函数),我门把当前的引用数打印出来为2这个没有题目,为什么在函数竣事时没有挪用工具的析构函数呢?这就仿佛多线程之间的死锁一样,工具a想要析构可是发明工具b引用了本身以是就守候工具b析构不再引用本身,而b想要析构却发明工具a引用了自又守候a析构云云就导致两个指针指向的工具没有析构开释内存,这就是轮回引用导致的内存题目。 怎样证明这个结论呢,我们手动开释掉两个工具对对方的引用,就可以扫除轮回引用相关,正确析构工具了(把注释部门代码打开)。运行功效: 我门可以看到,挪用reset函数开释引用相关后,指针的引用计数变为一,比及函数运行竣事,两个shared指针生命周期竣事挪用析构函数,工具的引用计数减为0,工具内存开释。 可是假如每次都要手动扫除引用来办理轮回引用,那么智能指针好像酿成了傻子指针了,这时辰尚有一个对象能办理,那就是weak_ptr,它不会改变所共享的shared_ptr的引用计数,纵然我门可以通过该指针会见它所指向的工具。 // // main.cpp // test // // Created by 杜国超 on 17/9/9. // Copyright © 2017年 杜国超. All rights reserved. // #include <iostream> #include <memory> #include <vector> using namespace std; class CObjB; class CObjA { public: CObjA() { cout << "CObjA Constructor..." << endl; } ~CObjA() { cout << "CObjA Destructor..." << endl;} void Say() {cout << "CObjA Say..." << endl; } shared_ptr<CObjB> GetPb() { return m_pb.lock(); } public: weak_ptr<CObjB> m_pb; // 在A中引用B }; class CObjB { public: CObjB() { cout << "CObjB Constructor..." << endl; } ~CObjB() { cout << "CObjB Destructor..." << endl; } void Say() {cout << "CObjB Say..." << endl; } shared_ptr<CObjA> GetPa() { return m_pa.lock(); } public: weak_ptr<CObjA> m_pa; // 在B中引用A }; int main() { shared_ptr<CObjA> tmpPa = make_shared<CObjA>(); shared_ptr<CObjB> tmpPb = make_shared<CObjB>(); tmpPa->m_pb = tmpPb; tmpPb->m_pa = tmpPa; std::cout << "CObjA referencr num:" << tmpPa.use_count() << endl; std::cout << "CObjB referencr num:" << tmpPb.use_count() << endl; if (tmpPa->GetPb()!= NULL){ tmpPa->GetPb()->Say(); } if (tmpPb->GetPa()!= NULL){ tmpPb->GetPa()->Say(); } } 这样就获得我门想要的功效了。最后说一句固然智能指针带来了许多利便,可是也要警惕行使它如故有许多坑等着我门,往后再作详述。 总结 以上所述是小编给各人先容的C++中的轮回引用,但愿对各人有所辅佐,假如各人有任何疑问请给我留言,小编会实时回覆各人的。在此也很是感激各人对编程小能力网站的支持! (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 蔚来股价周二收盘上涨9% 预计11月份公布强劲第三季度业绩
- 苹果iPhone 13 Pro机型有望采用LTPO技术屏幕 支持120Hz刷新
- 奔驰宝马合资出行公司 扩充运营车辆竟然买特斯拉汽车
- [图]Galaxy Tab S6继任者型号曝光:上市后或叫Galaxy Tab S
- acasis阿卡西斯推出首款雷电3接口WIFI6移动网卡:内置Intel
- 李国庆向合作伙伴致歉:夫妻间经济纠纷与员工和客户无关 不
- 国家人工智能标准化总体组发布 人工智能知识图谱疫情防控和
- 你以为SEO已死,但是它还活着,养站经验分享
- 苹果泰坦项目专利曝光 安详带与车顶也配安详气囊
- 华为畅享20 Pro 1999元起 全场景5G、90Hz高刷、4800万AI三摄