在显式调用时,析构函数被调用两次

Cyg*_*nus 22 c++ destructor

我用这段代码在C++中试验析构函数:

#include <iostream>

struct temp
{
    ~temp() { std::cout << "Hello!" << std::endl; }
};

int main()
{
    temp t;
    t.~temp();
}
Run Code Online (Sandbox Code Playgroud)

我看到"你好!" 正在打印两次.不应该调用析构函数释放对象,并且当它超出范围时不应该再次调用析构函数吗?或者还有其他一些概念吗?

(我不打算在实践中这样做.我只是想了解这里发生了什么.)

Jon*_*pan 43

它发生是因为你说它发生了.当变量超出范围时,始终会调用自动变量的析构函数.你也叫它.总共有两个电话.

调用一个对象的析构函数不会向C++发出信号,不再调用它,因为在正常执行中没有必要跟踪.

解决方案是永远不要手动调用析构函数.

  • 不.对象是*自动*,而不是*动态*.这意味着它没有在可以解除分配的位置分配(在大多数系统上,它在堆栈而不是堆上.)由于您的对象是自动分配的,并且没有动态分配的字段,因此它仍然是完全形成的范围的结束.这是高度特定于实现的行为,绝不能依赖于此. (7认同)
  • @Inverse:是的,根据[C++ 03 12.4/14](http://cs.nyu.edu/courses/summer12/CSCI-GA.2110-001/downloads/C++%20Standard%202003.pdf):如果为生命周期结束的对象调用析构函数,则行为未定义.从形式上讲,调用析构函数(手动或自动)表示生命周期结束. (6认同)
  • @Cygnus:它会导致未定义的行为. (3认同)

jco*_*der 20

调用析构函数不会释放对象.

析构函数用于清理对象的内部,然后在析构函数完成后释放对象本身.

这是对你也同样这样做,以你的方式有什么错误可以调用对象上删除两次,但它是这样做的错误.

只有极少数情况下你想手动调用析构函数,而这不是其中之一.在你使用placement new手动构建一个内存位置的对象时,它确实存在,然后需要能够在不释放内存的情况下对其进行破坏.