22

基本クラス (基準) から継承する継承クラス (基準) の大規模なセットがあります。criterionさんのコードはこちら

class criterion
{
public:
    virtual unsigned __int32 getPriorityClass() const = 0;
    virtual BOOL include(fileData &file) const = 0;
    virtual void reorderTree() = 0;
    virtual unsigned int directoryCheck(const std::wstring& directory) const = 0;
    virtual std::wstring debugTree() const = 0;
};

このクラスから派生したクラスの例:

class fastFilter : public criterion
{
public:
    void reorderTree() {};
    unsigned int  directoryCheck(const std::wstring& /*directory*/) const { return DIRECTORY_DONTCARE; };
    unsigned __int32 getPriorityClass() const { return PRIORITY_FAST_FILTER; };
};

class isArchive : public fastFilter
{
public:
    BOOL include(fileData &file) const
    {
        return file.getArchive();
    }
    std::wstring debugTree() const
    {
        return std::wstring(L"+ ISARCHIVE\n");
    };
};

ここにはデストラクタがまったくありませんが、これは基本クラスであるはずなので、空の仮想デストラクタを挿入する必要がありますか?:

virtual void ~criterion() = 0;

その仮想デストラクタ宣言が必要な場合、すべての中間クラスにも必要ですか? つまり、上記の fastFilter には仮想デストラクタも必要ですか?

4

4 に答える 4

51

はい - たとえそれが空であっても、基本クラスには仮想デストラクタが必要です。そうしないと、何かdeleteがベース ポインター/参照を介して派生オブジェクトになったときに、派生オブジェクトのメンバー オブジェクトが適切に破棄される可能性がなくなります。

派生クラスは、既定のデストラクタの動作以外の何かが必要でない限り、独自のデストラクタを宣言または定義する必要はありません。

于 2009-05-05T22:31:50.593 に答える
31

以下を挿入することをお勧めします。

virtual ~criterion() {}

C ++ 11以降= default;、空の本文の代わりに使用できます{}

これは、基本クラスのポインタからの削除に関する問題を回避するためです。そうしないと、派生クラスのデストラクタが呼び出されないため、メモリリークが発生します。

criterion *c = new fastFilter();
delete c; // leaks
于 2009-05-05T22:32:19.017 に答える
13

デストラクタを抽象化する必要はありません。空の実装を指定するだけです。

virtual ~criterion() { }

このように、すべての子クラスに実装する必要はありませんが、それぞれに(継承された)仮想デストラクタがあります。

于 2009-05-05T22:34:01.570 に答える
7

他の人がすでに答えたものからの1つの小さな変更:

それ以外の

virtual void ~criterion() = 0;

必要なバージョンは次のとおりです。

    virtual ~criterion() {}  //Note: Removed void as destructors not allowed 
                             //  a return type

仮想デストラクタの詳細については、FAQのこのリンクを参照してください。デストラクタを仮想にする必要があるのはいつですか。

于 2009-05-06T04:34:34.123 に答える