Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将";删去这句话;在基类指针中,如果有虚拟析构函数,是否删除派生类对象?_C++_Oop_Object_Virtual Destructor - Fatal编程技术网

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
(即,您删除的
指针的指针对象的静态类型)有一个虚拟析构函数(如果class
A
有一个虚拟析构函数,那么它将“做正确的事情”(即删除最派生的子对象,运行其所有析构函数等)。这也适用于多重继承。

多亏了
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在没有声明虚拟析构函数的情况下被销毁。主要是在海湾合作委员会。