0

私の質問は、この質問に基づいています:非仮想の親を持つ仮想クラスから継承する正しい方法

質問に記載されているケースでは、新しく割り当てられたオブジェクトの Three と Two の部分が破壊されていないため、リークしているという私の理解は正しいですか?

ソース:

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

1 に答える 1

1

それは正解です。メモリリークの定義は、作成したもの(したがって、その存続期間を管理する責任があるもの)を削除できない状況です。

その質問への回答が示すdelete oneように、指定されたオブジェクトのランタイムタイプが静的(宣言された)タイプであり、静的タイプには仮想デストラクタがありません。

C ++標準の該当するセクションは、次のとおりです。

§5.3.5/3:最初の選択肢(オブジェクトの削除)では、オペランドの静的タイプがその動的タイプと異なる場合、静的タイプはオペランドの動的タイプの基本クラスであり、静的タイプは仮想デストラクタまたは動作は未定義です。

解決策は、すべてのデストラクタを宣言するか、へvirtualのポインタを介してオブジェクトを削除しないことOneです。

于 2012-01-07T12:09:46.670 に答える