c++ - 显式调用析构函数

标签 c++ destructor undefined-behavior lifetime explicit-destructor-call

我偶然发现了以下代码片段:

#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();
}

文字说这个片段应该会导致运行时错误。现在,我不太确定,所以我尝试编译并运行它。有效。奇怪的是,尽管所涉及的数据很简单,但程序在打印“文本”后卡顿,仅在一秒钟后完成。

我添加了一个要打印到析构函数的字符串,因为我不确定显式调用这样的析构函数是否合法。该程序打印了两次字符串。所以我的猜测是析构函数被调用了两次,因为正常的程序终止不知道显式调用并尝试再次销毁对象。

一个简单的搜索证实,在自动化对象上显式调用析构函数是危险的,因为第二次调用(当对象超出范围时)具有未定义的行为。所以我对我的编译器(VS 2017)或这个特定程序很幸运。

关于运行时错误的文字是否完全错误?或者运行时错误真的很常见吗?或者也许我的编译器针对这种事情实现了某种防护机制?

最佳答案

A simple search confirmed that explicitly calling a destructor on an automated object is dangerous, as the second call (when the object goes out of scope) has undefined behaviour.

确实如此。如果您使用自动存储显式销毁对象,则会调用未定义的行为。 Learn more about it .

So I was lucky with my compiler (VS 2017) or this specific program.

我会说你是不幸的。 UB 可能发生的最好的(对你来说,编码器)是在第一次运行时崩溃。如果它看起来工作正常,那么崩溃可能会在 2038 年 1 月 19 日在生产中发生。

Is the text simply wrong about the runtime error? Or is it really common to have runtime error? Or maybe my compiler implemented some kind of warding mechanism against this kind of things?

是的,文字有点错误。 未定义的行为是未定义的。运行时错误只是众多可能性之一(包括鼻恶魔)。

关于未定义行为的好读物:What is undefined behavor?

关于c++ - 显式调用析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53262269/

相关文章:

c++ - 在 C++ 和 CUDA 中 malloc 一个复杂的<float>

c++ - 如何显示窗口和命令行提示符?

C++ 成员变量的析构函数?

c++ - 为什么需要在列表拼接功能cpp中使用列表参数

c++ - C:为什么K&R中写着EOF不适合char?

c++ - 获取具体进程内存空间

C++ 我可以期望所有编译器都不会破坏返回的拷贝吗?

C++ 麻烦的析构函数

c++ - 使用常用数学函数 exp() log() 时如何防止溢出?

c++ - 反向迭代器(第一个元素之前的一个)和未定义的行为?