简体   繁体   English

我需要显式调用基本虚拟析构函数吗?

[英]Do I need to explicitly call the base virtual destructor?

When overriding a class in C++ (with a virtual destructor) I am implementing the destructor again as virtual on the inheriting class, but do I need to call the base destructor?当在 C++ 中覆盖 class 时(使用虚拟析构函数),我在继承 class 上再次将析构函数实现为虚拟,但是我需要调用基析构函数吗?

If so I imagine it's something like this...如果是这样,我想它是这样的......

MyChildClass::~MyChildClass() // virtual in header
{
    // Call to base destructor...
    this->MyBaseClass::~MyBaseClass();

    // Some destructing specific to MyChildClass
}

Am I right?我对吗?

No, destructors are called automatically in the reverse order of construction.不,析构函数会以与构造相反的顺序自动调用。 (Base classes last). (最后是基类)。 Do not call base class destructors.不要调用基本 class 析构函数。

No you don't need to call the base destructor, a base destructor is always called for you by the derived destructor.不,您不需要调用基析构函数,派生析构函数始终为您调用基析构函数。 Please see my related answer here for order of destruction . 请在此处查看我的相关答案以了解销毁顺序

To understand why you want a virtual destructor in the base class, please see the code below:要了解为什么要在基础 class 中使用虚拟析构函数,请参阅以下代码:

class B
{
public:
    virtual ~B()
    {
        cout<<"B destructor"<<endl;
    }
};


class D : public B
{
public:
    virtual ~D()
    {
        cout<<"D destructor"<<endl;
    }
};

When you do:当你这样做时:

B *pD = new D();
delete pD;

Then if you did not have a virtual destructor in B, only ~B() would be called.然后,如果您在 B 中没有虚拟析构函数,则只会调用 ~B()。 But since you have a virtual destructor, first ~D() will be called, then ~B().但是因为你有一个虚拟析构函数,所以首先调用~D(),然后调用~B()。

What the others said, but also note that you do not have to declare the destructor virtual in the derived class.其他人所说的,但还要注意,您不必在派生的 class 中声明析构函数 virtual。 Once you declare a destructor virtual, as you do in the base class, all derived destructors will be virtual whether you declare them so or not.一旦你声明了一个虚拟的析构函数,就像你在基础 class 中所做的那样,无论你是否声明它们,所有派生的析构函数都将是虚拟的。 In other words:换句话说:

struct A {
   virtual ~A() {}
};

struct B : public A {
   virtual ~B() {}   // this is virtual
};

struct C : public A {
   ~C() {}          // this is virtual too
};

No. Unlike other virtual methods, where you would explicitly call the Base method from the Derived to 'chain' the call, the compiler generates code to call the destructors in the reverse order in which their constructors were called.不。与其他虚拟方法不同,您会从 Derived 显式调用 Base 方法以“链接”调用,编译器生成代码以按照调用构造函数的相反顺序调用析构函数。

No, you never call the base class destructor, it is always called automatically like others have pointed out but here is proof of concept with results:不,您永远不会调用基本 class 析构函数,它总是像其他人指出的那样自动调用,但这里是概念证明和结果:

class base {
public:
    base()  { cout << __FUNCTION__ << endl; }
    ~base() { cout << __FUNCTION__ << endl; }
};

class derived : public base {
public:
    derived() { cout << __FUNCTION__ << endl; }
    ~derived() { cout << __FUNCTION__ << endl; } // adding call to base::~base() here results in double call to base destructor
};


int main()
{
    cout << "case 1, declared as local variable on stack" << endl << endl;
    {
        derived d1;
    }

    cout << endl << endl;

    cout << "case 2, created using new, assigned to derive class" << endl << endl;
    derived * d2 = new derived;
    delete d2;

    cout << endl << endl;

    cout << "case 3, created with new, assigned to base class" << endl << endl;
    base * d3 = new derived;
    delete d3;

    cout << endl;

    return 0;
}

The output is: output 是:

case 1, declared as local variable on stack

base::base
derived::derived
derived::~derived
base::~base


case 2, created using new, assigned to derive class

base::base
derived::derived
derived::~derived
base::~base


case 3, created with new, assigned to base class

base::base
derived::derived
base::~base

Press any key to continue . . .

If you set the base class destructor as virtual which one should, then case 3 results would be same as case 1 & 2.如果您将基本 class 析构函数设置为虚拟的,那么案例 3 的结果将与案例 1 和 2 相同。

No. It's automatically called.不,它是自动调用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM