【问题标题】:Class and member destructors called twice类和成员析构函数调用了两次
【发布时间】:2020-11-29 09:55:49
【问题描述】:
class A
{
public:
    ~A()
    {
        std::cout << "A destroyed" << std::endl;
    }
};

class B
{
public:
    A a;
    ~B()
    {
        std::cout << "B destroyed" << std::endl;
    }
};

int main()
{
    B b;
    b.~B();
}

输出:

B destroyed
A destroyed
B destroyed
A destroyed

有人可以向我解释这里发生了什么吗?我希望输出是

B destroyed
A destroyed

(当 ~B() 被调用时,一次 ~A() 被调用)。

【问题讨论】:

  • 这称为“未定义行为”。只需阅读警告部分,其中解释了显式析构函数调用的语法。
  • 为什么要在代码中显式调用析构函数?
  • @πάνταῥεῖ 哦,我不知道我们不应该显式调用析构函数。
  • @Jamāl 希望我的回答能帮助你理解为什么你不需要调用析构函数。
  • 唯一需要显式调用析构函数的时候是在使用placement new 构造对象时。

标签: c++ explicit-destructor-call


【解决方案1】:

在有限范围内创建的任何对象都将在退出范围时被销毁。 意思是,如果您在堆栈上创建了一个对象,当堆栈折叠回来时,它将与该范围内声明的任何其他变量一起被销毁。 p>

唯一的例外是当您使用对象的动态分配时,使用关键字new,这会在上创建对象,这不会' t 自行清洁。但即便如此,调用delete 也会自行调用析构函数。

话虽如此,为了避免使用newdelete,以及为了更好的资源管理,有一些类型(例如智能指针)可以自行处理这些问题,这种技术称为资源分配是初始化(或RAII),这让事情变得更简单(你到了第一部分,所有都分配在堆栈上,因此在折叠时会自动调用析构函数)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2015-02-25
    • 2016-01-31
    • 1970-01-01
    • 2021-07-03
    • 2012-08-06
    相关资源
    最近更新 更多