此代码:
#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;
}
它只打印一行。
答案 0 :(得分:5)
您所拥有的是根据C ++标准的未定义行为:
一旦为一个对象调用了析构函数,该对象就不再存在;如果为生存期已结束(6.8)的对象调用析构函数,则行为未定义。 [示例:如果显式调用了自动对象的析构函数,并且随后以通常会隐式破坏对象的方式保留该块,则该行为是不确定的。 —结束示例] < / p>
您可以使用以下语句显式调用自动对象objD
的析构函数:
objD.~Derived();
对象的隐式破坏在其作用域的结尾}
处调用。
答案 1 :(得分:4)
您在堆栈上创建一个对象。该对象具有自动生命周期,由其周围范围管理。如果您手动调用析构函数,则您将执行编译器为您执行的操作,并且最终会出现未定义的行为。
答案 2 :(得分:2)
您调用析构函数,c ++在主函数之后或在不使用对象之后自动调用析构函数,然后进行析构函数调用。你做两次“免费”
答案 3 :(得分:2)
对象析构函数总是在对象超出范围时调用。这是C ++设计方式的基础部分,它启用内存安全异常,RAII等。首先手动调用析构函数对此没有任何影响,因此,如果您自己调用它,它将(很可能是UB)运行两次你可以看到。
手动调用析构函数几乎总是不正确的,并且会导致未定义的行为。一种允许的情况是,您通过“ placement new”在单独分配的内存中创建了一个对象。