从具有非虚拟父级的虚拟类继承的正确方法继续

发布于 2024-12-25 23:21:29 字数 761 浏览 1 评论 0原文

我的问题是建立在这个问题的基础上的: 从具有非虚拟父级的虚拟类继承的正确方法

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

来源:

#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;
}

My question is building on this question: Correct way to inherit from a virtual class with non-virtual parent.

Is my understanding right that in the case which is described in the question, the Three and Two part of new allocated object are leaking because they are not destructed?

Source:

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

窗影残 2025-01-01 23:21:29

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

正如该问题的答案所示,删除一个会调用未定义的行为(在大多数情况下会可能会转化为常规的旧内存泄漏,但情况可能会像 鼻恶魔)因为指定对象的运行时类型与其静态(声明的)类型不匹配,并且静态类型没有虚拟析构函数。

C++ 标准中适用的部分是:

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

解决方案是要么将所有析构函数声明为虚拟的,要么不通过指向 One 的指针删除对象。

Yes, that's correct. The definition of a memory leak is a situation where you are unable to delete something that you created (and whose lifetime you are therefore responsible for managing).

As the answers to that question indicate, delete one invokes undefined behavior (which in most cases will probably translate to a regular old memory leak, but things could be as bad as nasal demons) because the runtime type of the specified object does not match its static (declared) type, and the static type does not have a virtual destructor.

The applicable section from the C++ standard is this one:

§5.3.5/3: In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.

The solution is either to declare all of the destructors virtual, or not to delete the objects through a pointer to One.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文