我有一个类(A),它为其中一个字段使用堆内存分配.A类被实例化并作为指针字段存储在另一个类(B)中.
当我完成对象B时,我调用delete,我假设调用了析构函数...但是这也调用了A类中的析构函数吗?
从答案中,我接受了(请编辑,如果不正确):
class A B的实例调用B :: ~B();class Bdelete 应该显式地将delete所有堆分配的成员变量A;这个问题不同于' 何时/为什么要使用virtual析构函数?".
struct B {
virtual void foo ();
~B() {} // <--- not virtual
};
struct D : B {
virtual void foo ();
~D() {}
};
B *p = new D;
delete p; // D::~D() is not called
Run Code Online (Sandbox Code Playgroud)
问题:
~D()不会被称为肯定)吗?~D()是空的怎么办 它会以任何方式影响代码吗?new[]/ delete[]with时B* p;,~D()无论virtual析构函数是什么,都肯定不会被调用.它是未定义的行为还是定义明确的行为?我正在做虚拟析构函数的一个小实验来审查 - 想知道是否有人对以下内容有一个简单的解释(使用vs 2010):
我定义类层次结构ABCD,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有一个非虚拟的Distructor
在D类型的堆上分配4个对象 - 在前3个点指向A*,B*和C*的指针 - 将第4个作为完整性的D*.
删除C*和D*指针:完整的析构函数链以从D向下到A的相反顺序执行,释放所有内存.
删除B*:B然后运行析构函数(泄漏)
删除A*:只运行析构函数(泄漏)
任何人都可以解释为什么这是?
当在实验2中分配D类型opject时,它的直接基类(C)有一个虚拟析构函数 - 不能告诉编译器用Vptr跟踪它并知道内存类型?无论参考?
谢谢迈克