C++ で純粋仮想デストラクタが必要なのはなぜですか? 質問する

C++ で純粋仮想デストラクタが必要なのはなぜですか? 質問する

仮想デストラクタの必要性は理解しています。しかし、なぜ純粋な仮想デストラクタ? ある C++ の記事で、著者はクラスを抽象化したい場合には純粋仮想デストラクタを使用すると述べていました。

しかし、メンバー関数のいずれかを純粋仮想にすることで、クラスを抽象化することができます。

私の質問は

  1. デストラクタを実際に純粋仮想化するのはいつでしょうか? 誰か良いリアルタイムの例を挙げてもらえますか?

  2. 抽象クラスを作成するときに、デストラクタも純粋仮想にするのは良い習慣でしょうか? そうであれば、その理由は何でしょうか?

ベストアンサー1

  1. おそらく、純粋仮想デストラクタが許可されている本当の理由は、それを禁止すると言語に別のルールを追加することになり、純粋仮想デストラクタを許可しても悪影響は生じないため、このルールは必要ないからです。

  2. いいえ、昔ながらの仮想で十分です。

仮想メソッドのデフォルト実装を持つオブジェクトを作成し、それを抽象化して、誰にもオーバーライドを強制したくない場合は、特定のメソッドを使用すると、デストラクタを純粋仮想化することができます。あまり意味がないと思いますが、可能です。

コンパイラは派生クラスに対して暗黙のデストラクタを生成するので、クラスの作成者がデストラクタを生成しない場合は、派生クラスはない抽象クラスに純粋仮想デストラクタがあっても、派生クラスには何の影響もありません。単に基底クラスが抽象クラスになるだけです(カッパのコメント)。

また、すべての派生クラスには特定のクリーンアップ コードが必要であり、それを記述するためのリマインダーとして純粋仮想デストラクタを使用する必要があると想定することもできますが、これは不自然 (かつ強制されていない) であるように思われます。

注記:デストラクタは、純粋仮想もっている派生クラスをインスタンス化するための実装が必要です (はい、純粋仮想関数は実装を持つことができます。純粋仮想であるということは、派生クラスがこのメソッドをオーバーライドする必要があることを意味し、これは実装を持つこととは直交しています)。

struct foo {
    virtual void bar() = 0;
};

void foo::bar() { /* default implementation */ }

class foof : public foo {
    void bar() { foo::bar(); } // have to explicitly call default implementation.
};

おすすめ記事