当在c++中覆盖一个类(使用虚析构函数)时,我在继承类上再次实现了虚析构函数,但我需要调用基析构函数吗?

如果是这样的话,我想应该是这样的……

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

    // Some destructing specific to MyChildClass
}

我说的对吗?


当前回答

其他人说了什么,但还要注意,您不必在派生类中声明析构函数虚值。一旦将析构函数声明为虚函数,就像在基类中所做的那样,所有派生析构函数都将是虚函数,无论是否这样声明。换句话说:

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

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

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

其他回答

其他人说了什么,但还要注意,您不必在派生类中声明析构函数虚值。一旦将析构函数声明为虚函数,就像在基类中所做的那样,所有派生析构函数都将是虚函数,无论是否这样声明。换句话说:

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

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

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

不,析构函数是按照构造的相反顺序自动调用的。(基类最后)。不要调用基类析构函数。

不。它会被自动调用。

不,你不需要调用基析构函数,基析构函数总是由派生析构函数调用。请参阅我的相关回答在这里的破坏顺序。

要理解为什么要在基类中使用虚析构函数,请参阅下面的代码:

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


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

当你这样做时:

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

然后,如果在B中没有虚析构函数,则只会调用~B()。但是由于您有一个虚析构函数,首先将调用~D(),然后是~B()。

c++中的析构函数只有在基类析构函数声明为虚时才会自动按其构造的顺序(先派生后基)调用。

如果不是,则在删除对象时只调用基类析构函数。

示例:没有虚析构函数

#include <iostream>

using namespace std;

class Base{
public:
  Base(){
    cout << "Base Constructor \n";
  }

  ~Base(){
    cout << "Base Destructor \n";
  }

};

class Derived: public Base{
public:
  int *n;
  Derived(){
    cout << "Derived Constructor \n";
    n = new int(10);
  }

  void display(){
    cout<< "Value: "<< *n << endl;
  }

  ~Derived(){
    cout << "Derived Destructor \n";
  }
};

int main() {

 Base *obj = new Derived();  //Derived object with base pointer
 delete(obj);   //Deleting object
 return 0;

}

输出

Base Constructor
Derived Constructor
Base Destructor

示例:使用基本虚析构函数

#include <iostream>

using namespace std;

class Base{
public:
  Base(){
    cout << "Base Constructor \n";
  }

  //virtual destructor
  virtual ~Base(){
    cout << "Base Destructor \n";
  }

};

class Derived: public Base{
public:
  int *n;
  Derived(){
    cout << "Derived Constructor \n";
    n = new int(10);
  }

  void display(){
    cout<< "Value: "<< *n << endl;
  }

  ~Derived(){
    cout << "Derived Destructor \n";
    delete(n);  //deleting the memory used by pointer
  }
};

int main() {

 Base *obj = new Derived();  //Derived object with base pointer
 delete(obj);   //Deleting object
 return 0;

}

输出

Base Constructor
Derived Constructor
Derived Destructor
Base Destructor

建议将基类析构函数声明为虚值,否则会导致未定义的行为。

参考:虚析构函数