继续使用非虚拟父级从虚拟类继承的正确方法

时间:2012-01-07 11:52:12

标签: c++ inheritance virtual-destructor

我的问题是基于这个问题:Correct way to inherit from a virtual class with non-virtual parent

我的理解是正确的,在问题中描述的情况下,新分配对象的三部分和两部分是否泄漏是因为它们没有被破坏?

来源:

#include <iostream>

struct One
{
    ~One() {
        std::cout << "~One()\n";
    }
};

struct Two : One
{
    virtual ~Two() {
        std::cout << "~Two()\n";
    }

    virtual void test() = 0;
};

struct Three : Two
{
    virtual ~Three() {
        std::cout << "~Three()\n";
    }

    virtual void test() {
        std::cout << "Three::test()\n";
    }
};

int main()
{
    Two* two = new Three;
    two->test();

    One* one = two;
    delete one;
}

1 个答案:

答案 0 :(得分:1)

是的,这是正确的。内存泄漏的定义是您无法删除您创建的内容(因此您负责管理其生命周期)的情况。

正如该问题的answers所示,delete one调用未定义的行为(在大多数情况下可能转换为常规的旧内存泄漏,但事情可能与nasal demons一样糟糕)因为指定对象的运行时类型与其静态(声明)类型不匹配,并且静态类型没有虚拟析构函数。

C ++标准的适用部分是这一部分:

  

§5.3.5/ 3:在第一个备选(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型和静态类型的基类应该有一个虚拟析构函数或行为未定义。

解决方案要么声明所有析构函数virtual,要么通过指向One的指针删除对象。