虚函数和虚析构函数有什么区别?

What is the difference between virtual function and virtual destructor function?

class Base {
    public:
    virtual ~Base () { cout << "Base Dtor" << endl; }
    virtual void doSomething () { cout << "Base do something" << endl; }
};

class Derive : public Base {
    public:
    ~Derive () { cout << "Derive Dtor" << endl; }
    void doSomething () { cout << "Derive do something" << endl; }
};

当我尝试编写一些代码时:

Base* ptr = new Derive;
ptr->doSomething ();
delete ptr;

函数 doSomething() 调用正确。为什么调用派生析构函数,然后调用基析构函数?但是 doSomething() 只是调用派生的 class 的版本。析构函数和 doSomething() 也是函数,但为什么它们的行为不同?

Why the derived destructor is called and then base destructor is called?

因为析构函数总是会销毁所有子对象。这包括基地。

对象析构函数很特殊。是的,它们是函数,但它们实际上代表了一些特定的东西。即,销毁一个对象。

在你的例子中 Derive 是一个对象。但是通过继承,Derive 有一个名为 Base 的基础 class 子对象。也就是说,对于每个 Derive,还有一个 Base 生活在 那个 Derive 对象。

当您调用构造函数来创建 Derive 时,也会为 Base 子对象调用适当的构造函数(取决于您如何定义 Derive 构造函数)。因此,如果你摧毁一个 Derive,生活在其中的 Base 必须 被摧毁。

对析构函数的 virtual 调用实际上并没有改变这一点。它 virtual 的作用是允许系统 正确地 启动析构函数链。如果您没有将 Base 析构函数声明为 virtual,那么在基 class 指针上调用 delete 只会调用 ~Base。就不能跳继承图去调用~Derivedelete 表达式被赋予了一个 Base 指针来删除,这就是它的作用。

这与任何 virtual 调用的机制相同。如果您没有创建常规成员函数 virtual,而是在 Base class 指针上调用它,那么您会得到它的 Base 版本,即使有是同名的 Derive 版本。你需要 virtual 让编译器跳出继承图并找到正确的函数来调用。

但是一旦编译器知道正确的对象类型来启动析构函数链,对象析构链仍然会发生。 Derive 包含一个 Base,所以要销毁 Derive,它的 Base 也必须被销毁。

您覆盖了 doSomething 函数,这就是它仅在您声明的 Derive 对象上执行的原因。

你可以看到析构函数有不同的名字。当你调用某个对象的析构函数时,父亲的析构函数也会自动被调用。