在非虚拟析构函数的情况下自动调用父析构函数?

时间:2015-02-02 18:55:54

标签: c++ destructor

我有一个struct O,在第三方代码中定义。因为它是C代码,所以它不定义virtual destructor。 (就我而言,它来自win32 appi的OVERLAPPED struct

我正在修改的客户代码的class S源自class A,源自struct O

struct O{};
class A : public O{};
class S : public A{};

其中没有将其析构函数声明为virtual

如果在指向delete的指针上调用O,则会发生泄漏。肯定。

但是如果我在指向S的指针上调用delete,C ++标准会说明什么? 它会自动调用两个父类的析构函数,即使它们都没有声明它们的析构函数是虚拟的吗?它会释放父母的相对记忆区吗?

S * pS = new S;
delete S; // would this call the parent destructor?

3 个答案:

答案 0 :(得分:4)

关于

S * pS = new S;
delete S; // would this call the parent destructor?

是。 除了析构函数可能是一个无关紧要的无所事事的析构函数。

答案 1 :(得分:3)

  

如果我在指向S的指针上调用delete,C ++标准会说明什么?

它来自[class.dtor](N4296的§12.4/ 8):

  

执行析构函数体并破坏体内分配的任何自动对象后,a   类X的析构函数调用X的直接非变量非静态数据成员的析构函数,析构函数   对于X的直接基类,如果X是派生类最多的类(12.6.2),则它的析构函数调用   X虚拟基类的析构函数。

所以在这种情况下,我们调用~S(),然后调用S的直接基类(A)的析构函数,然后调用析构函数那些基类(O)。

析构函数的virtual - 只会以相反的顺序排列,即:

O* s = new S;
delete s;

在这种情况下,只调用~O() - 因为没有非静态数据成员,或直接基类或虚拟基类,所以没有别的事情要做。

答案 2 :(得分:0)

当然,派生类析构函数的每次调用都会导致所有父类的析构函数调用。但是如果删除的类是指向没有虚析构函数的基类的指针,则不会调用派生类析构函数(可能是资源泄漏)

struct A {};
struct B : A {};
struct C : B {};

int main() {
    B* p = new C;
    // This will clean up A and B, but leak the resources of C
    delete p;
}