我有一个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?
答案 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;
}