我有一个三级深度的类层次结构,如下所示:
class A {
public:
virtual ~A() {}
}
class B : public A {
public:
virtual ~B() {}
void foo(E *e) {
e->remove(this);
}
}
class C : public B {
public:
~C() {}
}
class E {
public:
void remove(A *a) {
delete a;
}
}
好的,我想知道当我在foo()
的对象上调用C
时会发生什么。它是要移除整个对象还是仅移除对象的B
和A
部分,并将C
部分留在内存中?
答案 0 :(得分:5)
是要删除整个对象还是只删除对象的B和A部分,并将C部分留在内存中?
没有。它将“做正确的事”(即,删除最派生的子对象,运行其所有析构函数等)提供A
(即指针指针的静态类型delete
)有一个虚拟析构函数(如果类A
有一个虚拟析构函数,它的所有后代都有它)。这也适用于多重继承。
答案 1 :(得分:2)
感谢A
中的虚拟析构函数,代码可以正常销毁C
的整个实例。
答案 2 :(得分:2)
delete
将始终释放指向的整个对象的内存。
这不适用于被调用的析构函数:它将尝试调用要删除的对象的静态类型的析构函数。
在多态方案中,这通常不是您想要的。考虑一下:
struct Base { };
struct Derived : Base
{
int* i;
Derived() : i(new int) { }
~Derived() { delete i; }
}
void bad()
{
Base* b = new Derived;
delete b;
}
bad()
导致内存泄漏,因为永远不会调用Derived
的析构函数。这是因为b的静态类型是Base*
,因此将调用Base::~Base
。 Base
中没有定义析构函数,因此编译器提供的默认实现执行,在此特定示例中不执行任何操作。
然而,这不适用于您的示例:您使根类'析构函数为虚拟,因此所有派生类的析构函数将作为析构函数调用的一部分执行。