virtual デストラクタ

この記事は,C++プログラマであるかを見分ける10の質問 - Life like a clown の「virtual デストラクタの概要および使用上の戦略について述べよ」に対する回答的な記事です.

virtual デストラクタの役割は,派生クラスのデストラクタも適切に実行されるようにすると言うものです.virtual の付いていないデストラクタを持つクラスを継承して new でインスタンスを生成し,その継承したクラスへのポインタを基底クラスで保持してしまうと,delete の際に基底クラスのデストラクタのみが実行されてしまうので,派生クラスのデストラクタが実行されずリソースの開放漏れなどの問題が発生します.

virtual デストラクタに関しては,以下の記事で話題になったので一度流れを追ってみるのが良いと思います.

さて. virtual デストラクタに関する戦略ですが,簡単に言うと「インターフェース的な使われ方をするクラス(継承される可能性があり,かつ派生クラスのインスタンスを基底クラスのポインタで保持する可能性がある)の場合にはデストラクタに virtual を付ける」と言うものになります.

多くの場合、仮想デストラクタに関しては、

  • ポリモルフィズムをするための基底クラスには仮想デストラクタを持たせよう。特に仮想関数を持つクラスは必ず仮想デストラクタを持たせよう。
  • 継承を目的としていないクラス、または継承を目的としていてもそれがポリモルフィズムを目的としないのならば仮想デストラクタを宣言すべきではない。

となると思います。

ある程度経験を積んだC++プログラマは絶対にvirtualデストラクタのないクラスを継承しない? - 神様なんて信じない僕らのために

ここで,問題になるのが「あるクラスがインターフェース的な使われ方をするかどうかは分からない(インターフェース的な使い方をされないと言う保証ができない)」と言うものです.この辺は各人のクラス設計の問題にもなってくるのですが,「取りあえず全部に virtual を付けよう」派の主な論拠もこの辺りに起因しそうです.

個人的には,ある程度利用範囲の限られるクラス(あるプロジェクト内でのみ使われるとか)で今後どんな追加的な修正が入るか予想できないような場合には,「取りあえず全部のデストラクタに virtual を付けておく」と言う選択肢を取るのも良いと思います.ただし,これがいきすぎて「全てのクラスのデストラクタには virtual を付けなければいけない」のようなコーディング規約になってしまう(あるいは,そう盲目的に信じてしまう)のは良くないだろうと言う感想です.