C ++:删除派生类实例的正确方法是什么?

时间:2012-06-10 18:39:40

标签: c++ inheritance destructor

假设我们有:

class A {
protected:
    int* iArr;
    float *fArr;
public:
    A(int* iArr,float *fArr);
    ~A();
}

class B : public A {
private:
    double *dArr;
public:
    B(int* iArr,float *fArr,double *dArr);
    ~B();
}

我的意思是它只会调用B的析构函数,但是当我在Visual C ++上运行它时,我看到在破坏B的实例时它会调用A然后调用B析构函数。

在派生类中编写析构函数的正确方法是什么?我总是需要假设父类会处理删除所有内容,但只有派生类有什么?

修改

  1. 如果是这样,那么如果孩子只使用覆盖函数扩展父类,那么这是否意味着我将孩子的析构函数留空了?

  2. 如果我想改变它怎么办?我的意思是,如果我只想要调用子析构函数?有没有办法做到这一点?

2 个答案:

答案 0 :(得分:6)

总之,是的。

父类的析构函数总是被自动调用。它的工作是释放父类使用的所有资源。

子类的析构函数负责释放特定于子类的内容。

此外,如果您通过指向父类的指针删除子类的实例,则需要使父类的析构函数为virtual。见When to use virtual destructors?

答案 1 :(得分:2)

A的析构函数应该是虚拟的。您的问题在于,如果您执行以下操作:

A* b = new B( iArr, fArr, dArr );
delete b;

然后B的析构函数不会被调用,因为b在被实例化为B时看起来像A和B的析构函数在虚拟表中没有条目,这意味着它不知道它在那里(即它认为它只是一个A)

编辑:

在回答1时,你可以将析构函数留空,或者你无法定义它。

在回答2时,你无法真正做到这一点。你最好拥有一个名为“Destroy”的虚拟保护函数或者从基类析构函数调用的东西。这是我能想到的唯一控制破坏的方式。