全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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++中的循环引用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# c++  # 循环引用  # 深入了解c++11 移动语义与右值引用  # 详解C++ 引用  # C++11 模板参数的“右值引用”是转发引用吗  # C++ Primer注解之引用和指针  # C++11的右值引用的具体使用  # 浅谈C++左值引用和右值引用  # 详解C++中指针和引用的区别  # C++11右值引用和转发型引用教程详解  # 解析C++引用  # 可以看到  # 死锁  # 小编  # 都要  # 一句  # 在此  # 也要  # 有很多  # 这就是  # 到我  # 这就  # 等着  # 可以通过  # 带来了  # 给大家  # 还有一个  # 使我  # 就得  # 在与  # 所述 


相关文章: 宝塔建站无法访问?如何排查配置与端口问题?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  建站之星导航菜单设置与功能模块配置全攻略  如何快速生成橙子建站落地页链接?  如何通过FTP服务器快速搭建网站?  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  如何通过WDCP绑定主域名及创建子域名站点?  怀化网站制作公司,怀化新生儿上户网上办理流程?  香港服务器租用费用高吗?如何避免常见误区?  SQL查询语句优化的实用方法总结  如何高效搭建专业期货交易平台网站?  专业公司网站制作公司,用什么语言做企业网站比较好?  如何通过西部数码建站助手快速创建专业网站?  海南网站制作公司有哪些,海口网是哪家的?  如何选择最佳自助建站系统?快速指南解析优劣  如何通过cPanel快速搭建网站?  如何在阿里云部署织梦网站?  网站制作价目表怎么做,珍爱网婚介费用多少?  建站主机选哪种环境更利于SEO优化?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  制作网站的过程怎么写,用凡科建站如何制作自己的网站?  html制作网站的步骤有哪些,iapp如何添加网页?  建站上市公司网站建设方案与SEO优化服务定制指南  建站主机数据库如何配置才能提升网站性能?  如何用好域名打造高点击率的自主建站?  建站主机如何选?性能与价格怎样平衡?  建站之星官网登录失败?如何快速解决?  MySQL查询结果复制到新表的方法(更新、插入)  招贴海报怎么做,什么是海报招贴?  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  如何选择靠谱的建站公司加盟品牌?  ,怎么用自己头像做动态表情包?  建站之星3.0如何解决常见操作问题?  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  网站网页制作专业公司,怎样制作自己的网页?  Python多线程使用规范_线程安全解析【教程】  如何在局域网内绑定自建网站域名?  如何获取上海专业网站定制建站电话?  活动邀请函制作网站有哪些,活动邀请函文案?  建站之星如何助力网站排名飙升?揭秘高效技巧  高端建站三要素:定制模板、企业官网与响应式设计优化  建站之星如何开启自定义404页面避免用户流失?  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  魔方云NAT建站如何实现端口转发?  建站主机选择指南:服务器配置与SEO优化实战技巧  如何快速生成专业多端适配建站电话?  魔毅自助建站系统:模板定制与SEO优化一键生成指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。