C++ 循环依赖解释
C++ Circular Dependency Explanation
我有一个使用智能指针的循环依赖的基本示例。
我一直在寻找一些解释,我知道如何解决这个问题,但我想知道幕后发生了什么。
这是代码:
#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;
}
}
谢谢
- 当调用shared_ptr析构函数时,它递减link计数,如果它变为零,则执行对象的析构函数并释放内存。
- 在
main()
函数结束后,两个共享指针被删除,因此它们的析构函数被执行,将儿子和爸爸的计数从 2 减少到 1。
循序渐进
Parent
在局部变量 parent
中创建并共享。为了便于阅读,我们将此分配称为 Parent。 Parent 计数 1
Child
在局部变量 child
中创建并共享。为了便于阅读,我们将此分配称为 Child。 Child 计数 1
parent
更新为指向 child
。 Child 计数 2
child
更新为指向 parent
。 Parent 计数 2
- 主要目的
child
销毁。 Child 计数 1
parent
销毁 Parent 计数 1
Child 和 Parent 不会被销毁,因为它们各自的计数永远不会达到零。程序退出并且 OS 回收所有内存,而没有它们的析构函数 运行。如果这是一个更大程序的一部分,Child 和 Parent 将继续在内存中占用 space 直到程序退出,除非采取一些极端的长度来定位它们,因为它们唯一外部 link 被摧毁。
我有一个使用智能指针的循环依赖的基本示例。 我一直在寻找一些解释,我知道如何解决这个问题,但我想知道幕后发生了什么。
这是代码:
#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;
}
}
谢谢
- 当调用shared_ptr析构函数时,它递减link计数,如果它变为零,则执行对象的析构函数并释放内存。
- 在
main()
函数结束后,两个共享指针被删除,因此它们的析构函数被执行,将儿子和爸爸的计数从 2 减少到 1。
循序渐进
Parent
在局部变量parent
中创建并共享。为了便于阅读,我们将此分配称为 Parent。 Parent 计数 1Child
在局部变量child
中创建并共享。为了便于阅读,我们将此分配称为 Child。 Child 计数 1parent
更新为指向child
。 Child 计数 2child
更新为指向parent
。 Parent 计数 2- 主要目的
child
销毁。 Child 计数 1parent
销毁 Parent 计数 1
Child 和 Parent 不会被销毁,因为它们各自的计数永远不会达到零。程序退出并且 OS 回收所有内存,而没有它们的析构函数 运行。如果这是一个更大程序的一部分,Child 和 Parent 将继续在内存中占用 space 直到程序退出,除非采取一些极端的长度来定位它们,因为它们唯一外部 link 被摧毁。