加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > 正文

C++中的轮回引用

发布时间:2020-12-30 12:16:15 所属栏目:创业 来源:网络整理
导读:固然C++11引入了智能指针的,可是开拓职员在与内存的斗争题目上并没有解放,假如我门适用不妥如故有内存走漏题目,个中智能指针的轮回引用缺陷是最大的题目。 //// main.cpp// test//// Created by 杜国超 on 17/9/9.// Copyright 2017年 杜国超. All rights

固然C++11引入了智能指针的,可是开拓职员在与内存的斗争题目上并没有解放,假如我门适用不妥如故有内存走漏题目,个中智能指针的轮回引用缺陷是最大的题目。

C++中的轮回引用

//
// 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析构云云就导致两个指针指向的工具没有析构开释内存,这就是轮回引用导致的内存题目。

怎样证明这个结论呢,我们手动开释掉两个工具对对方的引用,就可以扫除轮回引用相关,正确析构工具了(把注释部门代码打开)。运行功效:

C++中的轮回引用

我门可以看到,挪用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++中的轮回引用,但愿对各人有所辅佐,假如各人有任何疑问请给我留言,小编会实时回覆各人的。在此也很是感激各人对编程小能力网站的支持!

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读