ある程度経験を積んだC++プログラマは絶対にvirtualデストラクタのないクラスを継承しない?
ある程度経験を積んだC++プログラマは絶対にvirtualデストラクタのないクラスを継承しない
C++では基底クラスにvirtualデストラクタを書こう - *「ふっかつのじゅもんがちがいます。」withぬこ
はよくある間違い。あるいはC++初心者の勘違い。
継承する可能性のあるクラスにはすべてvirtualデストラクタを作る
C++では基底クラスにvirtualデストラクタを書こう - *「ふっかつのじゅもんがちがいます。」withぬこ
ということが否定されていることは言われるようにEffective C++を読んでいればわかること。
C++では、コピー不可にするために以下のようなクラスを書いたりするが、
(コピーコンストラクタとコピー代入演算子を無効にする)
class Uncopyable { protected: Uncopyable() {} ~ Uncopyable() {} private: Uncopyable(const Uncopyable&); Uncopyable& operator=(const Uncopyable&); };
こうしたクラスは継承に使われるが、仮想デストラクタを宣言することはない。
これらは、
class Hoge : private Uncopyable { public: Hoge(int value) : value_(value) {} private: int value_; }; // こうすると、 Hoge hoge1(1); Hoge hoge2(hoge1); // コンパイルエラー hoge2 = hoge1; // コンパイルエラー // になる。
codepadで実行してみる(コンパイルできないよ版)<-真似してみた
codepadで実行してみる(コンパイルできるよ版)
このように使われることを想定しているため、
Uncopyableは
空の基底クラスの最適化を期待するために「仮想デストラクタでないことが望ましいクラス」で
かつまた、「継承されることを目的としているクラス」です。
故に「絶対に」は言い過ぎです。
しかも、これらのことはEffective C++に書いてあります。
多くの場合、仮想デストラクタに関しては、
- ポリモルフィズムをするための基底クラスには仮想デストラクタを持たせよう。特に仮想関数を持つクラスは必ず仮想デストラクタを持たせよう。
- 継承を目的としていないクラス、または継承を目的としていてもそれがポリモルフィズムを目的としないのならば仮想デストラクタを宣言すべきではない。
となると思います。
C++ FAQ.より
実用的で簡単かつ憶えやすい指針を紹介しよう。
「あるクラスが仮想関数を持つならば、仮想デストラクタが必要になる。これに対して、クラスが全く仮想関数を持たないならばそのクラスが基底クラスとなる予定はないという設計なのだから、仮想デストラクタは不要だ」
とあります。
が、続けて
ただし、この指針がすべての環境下で適応できるほど正確でないことに注意しよう。
正確なルールは憶えるのがとても難しい代物なのだ。
ちなみに、これよりも正確なルールを紹介しよう。
「どのような派生クラス(もしくは、データメンバかつ/または(and/or)派生クラスの基底クラス、あるいは、派生クラスのデータメンバのデータメンバの基底クラス、あるいは、派生クラスのデータメンバの基底クラスと基底クラスとデータメンバの再帰的な組み合わせすべて)は、何らかの意味を持つデストラクタを持ち(あるいは、持つだろう)、そして、どこかに存在するコードが基底クラスのポインタを使って派生クラスを削除する可能性があるならば、基底クラスのデストラクタがvirtualである必要がある」
なにをいっているかわからねーと思うが
要するにC++はめんどくさいということだ。
やれやれ!
C++ FAQ 第2版 - C++プログラミングをきわめるためのQ&A集
- 作者: マーシャルクライン,マイクギルウ,グレッグロモウ,金沢典子
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2000/05/15
- メディア: 単行本
- 購入: 4人 クリック: 56回
- この商品を含むブログ (22件) を見る
Effective C++ 原著第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- 作者: スコット・メイヤーズ,小林健一郎
- 出版社/メーカー: ピアソン・エデュケーション
- 発売日: 2006/04/29
- メディア: 大型本
- 購入: 23人 クリック: 329回
- この商品を含むブログ (175件) を見る