C++ 为什么析构函数在';返回0';?

C++ 为什么析构函数在';返回0';?,c++,destructor,C++,Destructor,此代码: #include <iostream> class Base { }; class Derived : public Base { public: ~Derived() { std::cout<< "Derived dtor" << std::endl; } }; int main() { Derived objD; objD.~Derived(); 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;
}
我不知道第二行是从哪里来的

有了这一点:

int main()
{
    Derived objD;
    return 0;
}

它只打印一行。

在堆栈上创建一个对象。此对象具有由其周围范围管理的自动生存期。如果你手动调用析构函数,那么你就做编译器为你做的事情,然后你就得到了未定义的行为。

你调用析构函数,C++在main函数之后有一个自动调用析构函数,或者在对象不被使用之后,析构函数调用。你做了一个“免费”的< /P> < P>你这里的是按照C++标准定义的行为:

依照

一旦为对象调用析构函数,该对象就不再存在;如果为生存期已结束的对象调用析构函数,则该行为未定义(6.8)。[示例:如果显式调用自动对象的析构函数,并且随后以通常调用对象隐式销毁的方式保留块,则行为未定义。-结束示例]

使用以下语句显式调用自动对象的析构函数
objD

objD.~Derived();

对象的隐式销毁在其作用域结束时调用。当对象超出作用域时,始终调用关闭的
}

对象析构函数。这是C++设计的基本部分,它能实现内存安全异常、RAII等。手动调用析构函数首先与此无关,因此如果您自己调用它,它(最有可能的是,这是UB)运行两倍,您可以看到。
手动调用析构函数几乎总是不正确的,并且会导致未定义的行为。允许的一种情况是,您通过“placement new”在单独分配的内存中创建了一个对象。

objD
位于堆栈上,因此当它超出范围时,将调用它的析构函数,而不管您以前是否手动调用它。您不必-事实上也不能,在这种或几乎任何其他情况下-显式调用析构函数。当退出声明
objD
的作用域时,它已经自动完成。好吧。。。这就是它的工作原理。一旦你理解C++,你就会理解并喜欢这样的事实:析构函数是这样调用的。你几乎不应该自己调用析构函数,因此你现在有了UB。出于兴趣,你从哪里想到应该手动执行此操作?推论:除非你使用了新的位置,否则不要使用显式就地析构函数。使用布局新构造函数和显式就地析构函数的需求很少见,通常是高级C++编程技术(例如模板容器)。
objD.~Derived();