为什么在 'return 0' 之后调用析构函数?

Why destructor called after 'return 0'?

此代码:

#include <iostream>

class Base { };

class Derived : public Base
{
public:
    ~Derived()
    {
        std::cout<< "Derived dtor" << std::endl;
    }
};

int main()
{
    Derived objD;
    objD.~Derived();
    return 0;
}

打印:

Derived dtor // destructor called
Derived dtor // printed by 'return 0'

我不知道第二行是从哪里来的。

主要是:

int main()
{
    Derived objD;
    return 0;
}

它只打印一行。

您在堆栈上创建了一个对象。该对象具有由其周围范围管理的自动生命周期。如果您手动调用析构函数,您将执行编译器为您执行的操作,并且最终会出现未定义的行为。

你调用析构函数,c++在主函数之后自动调用析构函数,或者在对象未被使用之后调用析构函数。你做双 "free"

根据 C++ 标准,这里的行为是未定义的:

根据[class.dtor]/16

Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (6.8). [ Example: If the destructor for an automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined. —end example ]

您使用以下语句显式调用了自动对象 objD 的析构函数:

objD.~Derived();

并且对象的隐式销毁是在其作用域结束时调用的,即结束 }

当对象超出范围时,总是调用对象析构函数。这是 C++ 设计的基本部分,启用内存安全异常、RAII 等。首先手动调用析构函数与此无关,所以如果你自己调用它,它会(很可能,这是 UB)运行 如你所见的两倍。

手动调用析构函数几乎总是不正确的,并且会导致未定义的行为。允许的一种情况是当您通过 "placement new".

在单独分配的内存中创建对象时