有什么办法可以在类析构函数之前调用字段析构函数?
假设我有2个类Small
和Big
,并且Big
包含一个Small
as作为其字段的实例,例如:
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;
}
当然,这会在小析构函数之前调用大析构函数:
Big destructor
Small destructor
我需要在Small
析构函数之前调用该Big
析构函数,因为它会为Big
析构函数进行一些必要的清理。
我可以:
small.~Small()
显式调用析构函数。->但是,这Small
两次调用了析构函数:一次是显式的,一次是在Big
析构函数执行之后。Small*
作为的领域,并呼吁delete small;
在Big
析构函数我知道我可以在Small
类中有一个函数进行清理并在Big
析构函数中调用它,但是我想知道是否有一种方法可以逆转析构函数的顺序。
有什么更好的方法吗?
显式调用small。〜Small()析构函数。->但是,这两次调用了小析构函数:一次是显式调用,一次是在执行大析构函数之后。
好吧,我不知道为什么要继续使用这个有缺陷的设计,但是您可以使用new放置解决第一个项目符号中描述的问题。
它遵循一个最小的有效示例:
#include <iostream>
struct Small {
~Small() {std::cout << "Small destructor" << std::endl;}
};
struct Big {
Big() { ::new (storage) Small; }
~Big() {
reinterpret_cast<Small *>(storage)->~Small();
std::cout << "Big destructor" << std::endl;
}
Small & small() {
return *reinterpret_cast<Small *>(storage);
}
private:
unsigned char storage[sizeof(Small)];
};
int main() {
Big big;
}
您再也没有类型的变量Small
,但是使用small
示例中的成员函数之类的东西,您可以轻松地解决它。
这个想法是,您保留了足够的空间来就地构建a Small
,然后可以像您一样显式地调用它的析构函数。它不会被调用两次,因为Big
该类必须释放的全部是unsigned char
s数组。
而且,您不会Small
直接将其存储到动态存储中,因为实际上您是使用数据的成员Big
来创建动态存储的。
话虽如此,除非您有充分的理由,否则建议您在动态存储上分配它。使用astd::unique_ptr
并将其重置为的析构函数的开头Big
。您Small
将在析构函数的主体实际按预期执行之前就消失了,在这种情况下,析构函数也不会被调用两次。
编辑
如评论中所建议,std::optional
可以是另一个可行的解决方案std::unique_ptr
。请记住,这std::optional
是C ++ 17的一部分,因此,是否可以使用它主要取决于必须遵守的标准修订版本。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句