C ++破坏顺序:在类析构函数之前调用字段析构函数

CK。

有什么办法可以在类析构函数之前调用字段析构函数?

假设我有2个类SmallBig,并且Big包含一个Smallas作为其字段的实例,例如:

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析构函数进行一些必要的清理

我可以:

  1. small.~Small()显式调用析构函数。->但是,这Small两次调用了析构函数:一次是显式的,一次是在Big析构函数执行之后。
  2. 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 chars数组
而且,您不会Small直接将其存储到动态存储中,因为实际上您是使用数据的成员Big来创建动态存储的


话虽如此,除非您有充分的理由,否则建议您在动态存储上分配它。使用astd::unique_ptr并将其重置为的析构函数的开头BigSmall将在析构函数的主体实际按预期执行之前就消失了,在这种情况下,析构函数也不会被调用两次。


编辑

如评论中所建议,std::optional可以是另一个可行的解决方案std::unique_ptr请记住,这std::optional是C ++ 17的一部分,因此,是否可以使用它主要取决于必须遵守的标准修订版本。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章