C++ 将";删去这句话;在基类指针中,如果有虚拟析构函数,是否删除派生类对象?
我有一个三层的类层次结构,如下所示:C++ 将";删去这句话;在基类指针中,如果有虚拟析构函数,是否删除派生类对象?,c++,oop,object,virtual-destructor,C++,Oop,Object,Virtual Destructor,我有一个三层的类层次结构,如下所示: 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 *
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;
}
}
好的,我想知道的是,当我对C
的对象调用foo()
时会发生什么。它将删除整个对象还是仅删除对象的B
和A
部分,并将C
部分保留在内存中
它是要删除整个对象还是只删除B和对象的一部分,而将C部分仍保留在内存中
不可以。如果
A
(即,您删除的指针的指针对象的静态类型)有一个虚拟析构函数(如果classA
有一个虚拟析构函数,那么它将“做正确的事情”(即删除最派生的子对象,运行其所有析构函数等)。这也适用于多重继承。多亏了A
中的虚拟析构函数,代码将正常工作。销毁C
的整个实例将始终释放指向的整个对象的内存。
但是,这不适用于被调用的析构函数:它将尝试调用要删除的对象的静态类型的析构函数。
在多态场景中,这通常不是您想要的。考虑这一点:
struct Base { };
struct Derived : Base
{
int* i;
Derived() : i(new int) { }
~Derived() { delete i; }
}
void bad()
{
Base* b = new Derived;
delete b;
}
bad()
导致内存泄漏,因为派生的
s析构函数永远不会被调用。这是因为b的静态类型是Base*
,因此将调用Base::~Base
。在Base
中没有定义析构函数,因此编译器提供的默认实现将执行,而在这个特定示例中,它不执行任何操作
但是,这不适用于您的示例:您将根类的析构函数设置为虚拟,因此所有派生类的析构函数都将作为析构函数调用的一部分执行。您有语法错误。请把它们修好。此外,避免像瘟疫一样删除此
。另外,E类中的void remove(A*A)
,但是B类中的void remove(E*E)
?你确定吗?哎呀!您正在销毁所有对象,并释放其内存。代码中有2个删除。哪一种?析构函数的虚拟性是遗传性的。删除a后尝试访问类B实例的方法是检查这一点的另一种方法。对所有编译器都是这样吗?我发誓我见过C在没有声明虚拟析构函数的情况下被销毁。主要是在海湾合作委员会。