3

我有一个三层深的类层次结构,如下所示:

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在内存中?

4

3 回答 3

5

它是要删除整个对象还是只删除对象的 B 和 A 部分,而将 C 部分留在内存中?

不。它会“做正确的事”(即删除最派生的子对象,运行其所有析构函数等)提供A(即指针指针的静态类型 you delete)具有虚拟析构函数(如果类A有一个虚拟析构函数,它的所有后代也有它)。这也适用于多重继承。

于 2013-01-06T14:33:46.347 回答
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()导致内存泄漏,因为Deriveds 析构函数永远不会被调用。这是因为 b 的静态类型是Base*,因此Base::~Base会被调用。中没有定义析构函数Base,因此执行编译器提供的默认实现,在这个特定示例中什么都不做。

但是,这不适用于您的示例:您将根类的析构函数设为虚拟,因此所有派生类的析构函数都将作为析构函数调用的一部分执行。

于 2013-01-06T14:41:00.903 回答
2

多亏A了代码中的虚拟析构函数才能正确地销毁C.

于 2013-01-06T14:34:45.190 回答