销毁顺序 parent 和 child
Order of destruction parent and child
为什么 C++ 在 Child
class 之前析构 Parent
class?当 object 超出范围时首先销毁 shared_ptr
然后销毁自身不是更合乎逻辑吗?在我的工作流程中,这会导致问题,因为我的 Parent
class 正在管理 Child
classes 使用的接口。
#include <iostream>
#include <memory>
class Child;
class Parent
{
public:
Parent() :
child(std::make_shared<Child>())
{
std::cout << "Constructing parent" << std::endl;
}
~Parent() { std::cout << "Destructing parent" << std::endl; }
private:
std::shared_ptr<Child> child;
};
class Child
{
public:
Child()
{
std::cout << "Constructing child" << std::endl;
}
~Child() { std::cout << "Destructing child" << std::endl; }
};
int main()
{
Parent parent;
return 0;
}
编辑
根据评论,我觉得我的问题需要更多解释。我的 child classes 都分配在 std::shared_ptr
上,当 parent 超出范围时会被释放。我的主程序是CUDA程序,parent可以访问GPU设备。如果 parent 被删除,我将无法再访问 GPU。然而,children 的析构函数需要释放它们的 GPU 内存,因此我希望在 parent 超出范围之前执行此操作。但这意味着我必须手动删除智能指针,在我看来,这有点违背了它们的目的。
destruction order 定义为(强调我的):
For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct non-virtual base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.
一个很好的理由是 Parent
的析构函数可能需要访问其成员以释放资源,并非每个对象都是 self-contained。
Would it not be more logical for an object when its goes out of scope to first destruct the shared_ptrs and then destruct itself?
不一定,Parent
的析构函数可能需要访问某些成员以进行某种清理,因此它们需要在构造函数体内可访问并处于活动状态。如果您需要先销毁 Child
,您可以随时手动进行:
~Parent() {
child.reset();
// do the rest ...
}
为什么 C++ 在 Child
class 之前析构 Parent
class?当 object 超出范围时首先销毁 shared_ptr
然后销毁自身不是更合乎逻辑吗?在我的工作流程中,这会导致问题,因为我的 Parent
class 正在管理 Child
classes 使用的接口。
#include <iostream>
#include <memory>
class Child;
class Parent
{
public:
Parent() :
child(std::make_shared<Child>())
{
std::cout << "Constructing parent" << std::endl;
}
~Parent() { std::cout << "Destructing parent" << std::endl; }
private:
std::shared_ptr<Child> child;
};
class Child
{
public:
Child()
{
std::cout << "Constructing child" << std::endl;
}
~Child() { std::cout << "Destructing child" << std::endl; }
};
int main()
{
Parent parent;
return 0;
}
编辑
根据评论,我觉得我的问题需要更多解释。我的 child classes 都分配在 std::shared_ptr
上,当 parent 超出范围时会被释放。我的主程序是CUDA程序,parent可以访问GPU设备。如果 parent 被删除,我将无法再访问 GPU。然而,children 的析构函数需要释放它们的 GPU 内存,因此我希望在 parent 超出范围之前执行此操作。但这意味着我必须手动删除智能指针,在我看来,这有点违背了它们的目的。
destruction order 定义为(强调我的):
For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct non-virtual base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.
一个很好的理由是 Parent
的析构函数可能需要访问其成员以释放资源,并非每个对象都是 self-contained。
Would it not be more logical for an object when its goes out of scope to first destruct the shared_ptrs and then destruct itself?
不一定,Parent
的析构函数可能需要访问某些成员以进行某种清理,因此它们需要在构造函数体内可访问并处于活动状态。如果您需要先销毁 Child
,您可以随时手动进行:
~Parent() {
child.reset();
// do the rest ...
}