【问题标题】:When is it necessary to make explicit destructor calls?什么时候需要显式地调用析构函数?
【发布时间】:2013-09-04 10:18:35
【问题描述】:

是否存在使用标准new/delete 不够的情况,我们需要显式调用析构函数,例如pA->~A()?

我认为它仅在某些资源管理类中是必需的,但通常不是一个好主意。析构函数在作用域结束时自动调用,那么我为什么要自己显式调用它呢?

举例说明就好了!

【问题讨论】:

    标签: c++ scope destructor


    【解决方案1】:

    在 C++11 中,您可以使用需要析构函数的类型的 union。由于编译器不会跟踪当前处于活动状态的类型,因此您需要在替换当前活动成员或销毁 union 时显式销毁当前成员。

    在 9.5 [class.union] 第 4 段中,标准使用以下示例代码从当前活动成员 m 切换到新活动成员 n:

    u.m.~M();
    new (&u.n) N;
    

    【讨论】:

    • +1 直到您可以放置​​-new(并手动销毁)union 成员,至少在 C++11 中。我似乎记得这(并且通常在unions 中使用非 POD 类型)是 C++03 中的 UB ....
    • @ChrisJester-Young:我认为这不是 C++03 中未定义的行为:我认为在 C++03 中,编译器在尝试使用非POD 作为union 的成员。
    【解决方案2】:

    另一个使用显式析构函数调用的实例是使用放置new手动构造的对象。

    假设您尝试使用与malloc/free 兼容的 API(例如,用于与允许指定自定义 C 样式分配器的 C 客户端交互):

    void* buf = malloc(sizeof (MyType));
    if (buf) {
        MyType* foo = new (buf) MyType;
        // ...
        foo->~MyType();
        free(buf);
    }
    

    (不过,在这种情况下,最好只使用带有自定义删除器的 shared_ptr 或 unique_ptr。)

    【讨论】:

    • 你的意思是打电话给delete吗?可以举个例子吗?
    • @Oleksiy 您只能将delete 用于使用new 分配的对象。我提供了一个示例,其中使用 malloc 分配对象底层的内存。
    • 调用 delete foo 不等同于 foo->~MyType();免费(缓冲区); ?
    • @computer 不,delete 不(necessarily)使用free,就像new 不(必然)使用malloc。 C++ 系统有自己的分配器,默认 new 和 delete 使用。无论如何,这都是无关紧要的,因为我的示例应该可以推广到 C 客户端指定自定义分配器(使用 malloc/free 接口)的情况。
    • @computer 您不能在使用malloc 分配内存的对象上使用delete。这是因为malloc 使用的内存区域可能与new 使用的内存区域不同。 new 是 allowed, but not required,在幕后使用 malloc。
    猜你喜欢
    • 2022-01-19
    • 2019-04-07
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 2014-04-24
    相关资源
    最近更新 更多