【发布时间】:2012-06-18 18:49:22
【问题描述】:
我正在用虚拟析构函数做一个小实验来复习 - 想知道是否有人对以下内容有简单的解释(使用 vs 2010):
我定义类层次A-B-C-D,D继承C,C继承B,B继承A,A是Base;
进行了 2 次实验:
第一次实验-
A 有一个虚拟析构函数。
B 有一个非虚拟析构函数
C 有一个虚拟析构函数
D 有一个非虚析构函数
//----------------------------
在 D 类型的堆上分配 4 个对象 - 在前 3 个指向 A*、B* 和 C* 的指针 - 将第 4 个保留为 D* 以保证完整性。 删除所有 4 个指针。
正如我所料,在所有 4 个实例中,完整的析构函数链都以从 D 到 A 的相反顺序执行,释放所有内存。
第二次实验-
A 有一个非虚拟析构函数 ** 将 A 更改为非虚拟
B 有一个非虚拟析构函数
C 有一个虚拟析构函数
D 有一个非虚析构函数
在 D 类型的堆上分配 4 个对象 - 在前 3 个指向 A*、B* 和 C* 的指针 - 将第 4 个保留为 D* 以保证完整性。
删除 C* 和 D* 指针: 完整的析构链从 D 到 A 以相反的顺序执行,释放所有内存。
删除 B*: B 然后运行 A 析构函数(泄漏)
删除 A*: 只运行一个析构函数(泄漏)
谁能解释这是为什么?
当在实验 2 中分配 D 类型对象时,它的直接基类 (C) 有一个虚拟析构函数 - 不是告诉编译器用 Vptr 跟踪它并知道内存类型吗?不考虑参考文献?
谢谢 迈克
【问题讨论】:
-
如果您提供了示例代码,那就太好了。
-
@Rook 我已经发布了一个代码 sn-p 来说明这种情况(几乎相同) - 如果有任何 cmets,请告诉我。