CK.*_*CK. 6 c++ destructor object-destruction
有没有办法在类析构函数之前调用字段析构函数?
假设我有 2 个类Small和Big,并且Big包含一个Small作为其字段的实例,如下所示:
class Small
{
public:
~Small() {std::cout << "Small destructor" << std::endl;}
};
class Big
{
public:
~Big() {std::cout << "Big destructor" << std::endl;}
private:
Small small;
};
int main()
{
Big big;
}
Run Code Online (Sandbox Code Playgroud)
当然,这在小析构函数之前调用大析构函数:
Big destructor
Small destructor
Run Code Online (Sandbox Code Playgroud)
我需要在Small析构函数之前调用Big析构函数,因为它为Big析构函数做了一些必要的清理工作。
我可以:
small.~Small()显式调用析构函数。-> 然而,这Small两次调用析构函数:一次显式调用,一次在Big析构函数执行后。Small*作为的领域,并呼吁delete small;在Big析构函数我知道我可以在Small类中有一个函数来进行清理并在Big析构函数中调用它,但我想知道是否有办法反转析构函数的顺序。
有没有更好的方法来做到这一点?
\n\n\n显式调用\xc2\xa0small.~Small()\xc2\xa0析构函数。-> 但是,这会调用小析构函数两次:一次是显式调用,另一次是在执行大析构函数之后。
\n
好吧,我不知道您为什么要继续使用这种有缺陷的设计,但是您可以使用新的放置来解决第一个项目符号中描述的问题。
\n它遵循一个最小的工作示例:
#include <iostream>\n\nstruct Small {\n ~Small() {std::cout << "Small destructor" << std::endl;}\n};\n\nstruct Big {\n Big() { ::new (storage) Small; }\n\n ~Big() {\n reinterpret_cast<Small *>(storage)->~Small();\n std::cout << "Big destructor" << std::endl;\n }\n\n Small & small() {\n return *reinterpret_cast<Small *>(storage);\n }\n\nprivate:\n unsigned char storage[sizeof(Small)];\n};\n\nint main() {\n Big big;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n您不再有 type 的变量Small,但是使用示例中的成员函数之类的东西,small您可以轻松解决它。
这个想法是,您保留足够的空间来构造就地 a Small,然后您可以像您一样显式调用其析构函数。它不会被调用两次,因为该类Big必须释放的只是一个 s 数组unsigned char。
\n此外,您不会Small直接将您存储到动态存储中,因为实际上您正在使用您的数据成员Big来创建它。
话虽这么说,我建议您将其分配在动态存储上,除非您有充分的理由不这样做。使用 astd::unique_ptr并在 的析构函数的开头重置它Big。在析构函数的主体实际按预期执行之前,您的Small意志就会消失,而且在这种情况下,析构函数不会被调用两次。
编辑
\n\n正如评论中所建议的,std::optional可以是另一种可行的解决方案而不是std::unique_ptr. 请记住,这std::optional是 C++17 的一部分,因此您是否可以使用它主要取决于您必须遵守的标准的修订版本。
| 归档时间: |
|
| 查看次数: |
1387 次 |
| 最近记录: |