我偶然发现了以下代码片段:
#include <iostream>
#include <string>
using namespace std;
class First
{
string *s;
public:
First() { s = new string("Text");}
~First() { delete s;}
void Print(){ cout<<*s;}
};
int main()
{
First FirstObject;
FirstObject.Print();
FirstObject.~First();
}
这段文字说这个代码片段应该会导致运行时错误。但我并不确定,于是我尝试编译和运行它。它能够正常工作。奇怪的是,尽管涉及的数据很简单,程序在打印“Text”后有所迟滞,仅在一秒钟后才完成。
由于不确定显式调用析构函数是否合法,我添加了一个字符串以便在析构函数中打印出来。程序打印了两次该字符串。因此我的猜测是,当程序正常结束时不知道显式调用,尝试再次销毁该对象,因此析构函数被调用两次。
简单的搜索确认了,在自动化对象上显式调用析构函数是危险的,因为第二次调用(当对象超出其范围时)具有未定义的行为。因此我很幸运,我的编译器(VS 2017)或者这个特定的程序可能实现了某种防护机制来避免这种情况发生。
这段文字中提到的运行时错误是不是真的存在呢?还是这种情况很常见?或者也许我的编译器实现了某种防护机制以避免这种情况发生?
noexcept
函数是对std::terminate
的保证调用,我会将其归类为运行时错误。 - chriss
,而不是对象本身。我的错误。 - Mark Ransom