为什么在 '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++ 标准,这里的行为是未定义的:
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".
在单独分配的内存中创建对象时
此代码:
#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++ 标准,这里的行为是未定义的:
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".
在单独分配的内存中创建对象时