C ++循环依赖性解释

时间:2016-04-04 20:39:08

标签: c++ smart-pointers circular-dependency

我有一个使用智能指针的循环依赖的基本示例。 我一直在寻找一些解释,我知道如何解决这个问题,但我想知道它在幕后发生了什么。

这是代码:

#include <iostream>
#include <memory>
using namespace std;

class Child;
class Parent {
  public:
    shared_ptr<Child> child;
    string name;
    Parent(string n) : name(n) {
      cout << "Parent: " << name << " constructor" << endl;
    }
    ~Parent() {
      cout << "Parent: " << name << " destructor" << endl;
    }
};

class Child {
  public:
    shared_ptr<Parent> parent;
    string name;
    Child(string n) : name(n) {
      cout << "Child: " << name << " constructor" << endl;
    }
    ~Child() {
      cout << "Child: " << name << " destructor" << endl;
    }
};

int main(int argc, char** argv) {
  shared_ptr<Parent> parent = make_shared<Parent>("Dad");//parent.use_count() => 1
  shared_ptr<Child> child = make_shared<Child>("Child");//child.use_count() => 1
  parent->child = child;//child.use_count() => 2
  child->parent = parent;//parent.use_count() => 2
  return 0;
}
//what happend at the end of the program?
//what happend when the shared_ptr destructors were called?
//was parent.use_count() decremented or is still 2?
//was child.use_count() decremented or is still 2?

输出:

Parent: Dad constructor
Child: Child constructor

我想知道的是以下

  • 调用shared_ptr析构函数时会发生什么?
  • 是parent.use_count()递减还是2?
  • 是child.use_count()递减还是2?

我认为shared_ptr析构函数代码类似于:

~shared_ptr() {
  //I want to know what it is happening right here
  if (canDeletePointer(pointer)) {
    delete pointer;
  }
}

由于

2 个答案:

答案 0 :(得分:2)

  • 当调用shared_ptr析构函数时,它会减少链接计数,如果它变为零,它会执行对象的析构函数并释放内存。
  • main()函数结束后,两个共享指针被删除,因此执行了它们的析构函数,将父亲和父亲的计数从2减少到1。

答案 1 :(得分:0)

一步一步

  1. Parent已在本地变量parent中创建并共享。为了便于阅读,我们将此分配称为Parent。父母数1
  2. Child已在本地变量child中创建并共享。为了便于阅读,我们将此分配称为Child。儿童数1
  3. parent已更新为指向child。儿童数2
  4. child已更新为指向parent。父母数2
  5. 主要目的
  6. child被毁。儿童数1
  7. parent销毁了父数1
  8. 儿童和父母不会被销毁,因为他们各自的计数永远不会达到零。程序退出,操作系统回收所有内存而不运行析构函数。如果这是一个较大程序的一部分,Child和Parent将继续占用内存空间,直到程序退出,除非采取一些极端的长度来定位它们,因为它们唯一的外部链接被破坏了。