基类析构函数中虚函数调用的多态能力

Polymorph ability of virtual function called in destructor of base class

本文关键字:多态 能力 函数调用 析构函数 基类      更新时间:2023-10-16
#include <iostream>
#include <map>
using namespace std;
class Base
{
public:
    int m_nValue;
    Base()
    {
    }
    virtual ~Base()
    {
        Clear();
    }
    virtual void Clear()
    {
        cout << "Destroy Base." << endl;
    }
};
class Derived: public Base
{
public:
    Derived()
    {
    }
    void Clear() override
    {
        cout << "Destory Derived." << endl;
    }
};
int main()
{
    Derived* d = new Derived();
    delete d;
}

打印"摧毁基地"。我是c++新手,有人能告诉我为什么会这样吗?为什么不打印"销毁派生"。

当(就在)类型T的构造函数体开始执行时,对象的动态类型调整为T

这意味着虚拟调用将像最初创建的类型为T的对象一样解析。

这是一个相当昂贵的机制,所以它有一个非常重要的原因:为了避免调用派生类D中的虚函数实现m,其中D::m的¹假设尚未建立。这样的向下调用是Java中常见的bug来源。这在c++中是不会发生的。

最后调用的构造函数体是最派生类的构造函数体,该类用于创建对象。这就是对象最终的动态类型

相反,当对象被销毁时,会发生相反的情况:一系列动态类型调整为更一般的类型。本质上,在类T的析构函数体执行期间,对象的动态类型是T。就像在执行T构造函数体时一样。


<一口> 指出:
¹类T的成员函数的上下文无关假设是T对象状态的一般假设,例如其成员变量值之间的关系。这被称为T类不变量。因此,c++动态类型调整机制有助于确保只有构造函数和析构函数必须处理尚未完全建立的类不变式:在c++中(但例如在Java或c#中不是这样),所有其他成员函数都可以盲目地假设类不变式已经建立。