めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

C++の純粋仮想デストラクタって何に使うの?

こんばんは、めのんです!

昨日も書いたように、休日はできるだけPHP以外の話題にも触れていきたいと考えています。 というわけで、今回もC++についてです。

クラスについては、最近の主だったプログラミング言語であれば、シンタックスの違いぐらいで基本的なところはそんなに大きく変わりません。 一部例外はあるんですけどねー

で、その主だったプログラミング言語の中での違いといえば、デフォルトでメソッドをオーバーライドできるかどうか、デストラクタがあるかどうか、多重継承ができるどうか、データメンバーをあとから追加できるかどうかといったところではないでしょうか?

私が調べた範囲では、PHPJavaはデフォルトでメソッドをオーバーロードできますが、C++C#は明示的にvirtualを指定しないとオーバーライドできません。 JVMを使う前提のKotlinがデフォルトではオーバーライドできないのは面白いと思いました。

デストラクタの有無については微妙なんですが、PHPC++はスコープから抜けるときに呼ばれるデストラクタがあるので、よく似ていると思います。 GCがメモリを解放する際にファイナライザが呼ばれる言語もありますね。 C#なんかはusingステートメントから抜ける際にもDisposeが呼ばれるので、中間的な位置づけかもしれません。 Javaも最近はちょっとそれに近づいたそうですね。

多重継承やデータメンバーがどうこういうのは今回は省略します。

先ほども書いたように、C++では明示的にvirtualを指定したメソッド(C++ではメンバー関数と呼ぶ方が適切でしょうね)だけがオーバーロードできます。 そして、メンバー関数の宣言時に末尾に = 0 をつければ、それは純粋仮想関数になります。 純粋仮想関数を持つクラスは抽象クラスになるので、純粋仮想関数を派生クラスでオーバーライドしてあげないとその派生クラスのオブジェクトを構築することができません。

そこまではいいんです。

C++では、どういうわけかデストラクタまで純粋仮想関数にできてしまうんですよ。 そのくせ、純粋仮想関数のはずのデストラクタの実態を定義してあげないとリンクエラーになってしまいます。

この純粋仮想デストラクタ(純粋仮想関数のデストラクタ)って、いったい何に使うんでしょうね? 抽象クラスにしたいだけなんでしょうか? でも、デストラクタ以外にも仮想関数はあるでしょうし、逆に言えばデストラクタだけが仮想関数でも意味ないと思うんですけど。

この辺り、考えれば考えるほど謎が深まります。 きっとベテランのC++プログラマーにとっては常識なんでしょうけど、駆け出しの私はまだまだ精進が必要なようです。

結論が出ないままになりましたが、詳しい方がいらっしゃいましたら是非教えてくださいね。

それでは!!