首页 文章

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

提问于
浏览
295

在C中覆盖一个类(使用虚拟析构函数)时,我在继承类上再次将析构函数实现为虚拟,但是我是否需要调用基础析构函数?

如果是这样,我想它就是这样......

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

    // Some destructing specific to MyChildClass
}

我对吗?

6 回答

  • 9

    不,您不需要调用基础析构函数,派生析构函数总是为您调用基础析构函数 . Please see my related answer here for order of destruction .

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

    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() .

  • 5

    否 . 与其他虚拟方法不同,您将显式调用Derived中的Base方法来“调用”链接,编译器会生成代码,以按照调用构造函数的相反顺序调用析构函数 .

  • 84

    其他人说了什么,但也注意到你不必在派生类中声明析构函数virtual . 一旦声明了析构函数virtual,就像在基类中那样,所有派生的析构函数都是虚拟的,无论你是否声明它们 . 换一种说法:

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

    不,你从不调用bese类析构函数,它总是像其他人指出的那样自动调用,但这里是结果的概念证明:

    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;
    }
    

    输出是:

    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 . . .
    

    如果将基类析构函数设置为虚拟的,那么案例3的结果将与案例1和2相同 .

  • 6

    不,以相反的构造顺序自动调用析构函数 . (基础课最后) . 不要调用基类析构函数 .

  • 399

    不,它是自动调用的 .

相关问题