为什么C ++在Parent
类之前会破坏Child
类?当一个对象超出范围首先破坏shared_ptr
然后破坏自身时,它是否更合乎逻辑?在我的工作流程中,这会导致问题,因为我的Parent
类正在管理Child
类使用的接口。
#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;
}
修改
根据评论,我觉得我的问题需要更多的解释。我的子类都在std::shared_ptr
上分配,当父级超出范围时,它会被释放。我的主程序是CUDA程序,父程序可以访问GPU设备。如果父项被删除,我将无法再访问GPU。然而,孩子们的析构函数需要释放他们的GPU内存,因此我希望在父母退出范围之前采取这一行动。但这意味着我必须手动删除智能指针,在我看来,这有点挫败了它们的目的。
答案 0 :(得分:5)
destruction order被定义为(强调我的):
对于用户定义或隐式定义的析构函数,在执行析构函数体之后,编译器调用类的所有非静态非变体成员的析构函数,反之为声明的顺序,然后它按照构造的相反顺序调用所有直接非虚拟基类的析构函数(反过来调用它们的成员及其基类的析构函数等),然后,如果这个对象最多 - 派生类,它调用所有虚拟基础的析构函数。
一个很好的理由是Parent
的析构函数可能需要访问其成员以释放资源,而不是每个对象都是自包含的。
答案 1 :(得分:2)
当一个对象超出范围首先破坏shared_ptrs然后自毁时,它是否更合乎逻辑?
实际上,Parent
的析构函数可能需要访问某些成员来进行某种清理,因此它们需要在构造函数体内可访问和存活。如果您需要首先销毁Child
,您可以随时手动执行此操作:
~Parent() {
child.reset();
// do the rest ...
}