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三摄




