p655〜p667まで

土日サボってた。あうあう。

インタフェースクラス

仮想継承を使ったインタフェースクラスは作ったことなかった。というか、仮想継承の存在を忘れていたわけで。

・インタフェースクラスを仮想継承すれば、どんなに複雑な多重継承を行っても継承されたすべてのインタフェースクラスはそれぞれ1つずつしか存在しない。

やはり仮想継承の利点はオブジェクトが必ず1つというところにあるようだ。多重継承使わない限りはあんまりお世話にならないかなぁ。

typeid

これまた使ったことのないtypeid演算子。RTTIってやつですな。名前だけ知ってます><。正式な綴りはRun Time Type Information。訳すと実行時型情報。

・実行時の型を調べるために使う。
・typeid(値 or 型)といった形で使い、type_infoクラスあるいはその派生クラスのオブジェクトへのconst参照を返す。このオブジェクトの寿命はプログラム終了時まで続く。type_infoクラスはtypeinfoヘッダに定義されている。
例)

cout << typeid(cout).name() << endl;
// coutもクラスor型だったのをはじめて知った。

実行結果(出力される文字列)はコンパイラによって結構違うみたい。
・トップレベル(その変数自身)のconstや参照はtypeidでは無視される。 = 元の型を調べるためにconstや参照をつけたパターンで調べなくてもよい。
・RTTIは仮想関数が1つでもなければ使えない。

基本的にはアップキャストと後述するダウンキャストされたオブジェクトに対して使われる。

ダウンキャストとクロスキャスト

まぁここらへんは抑えてるので確認程度で。

・派生クラスへキャストすることをダウンキャストと呼び、非常に危険なキャスト。
・継承木を下がって上がるようなキャストのことをクロスキャストと呼ぶ。多重継承した場合に見られる。
・ダウンキャストをする場合や、継承木をいろいろとたどりたい場合はdynamic_castを使用するのがよい。
・参照型へのdynamic_castが失敗するとbad_castという例外が投げられる。ポインタへのdynamic_castが失敗するとヌルポインタが返ってくる。

パフォーマンスが気になるときにはポインタでdynamic_castした方が例外投げないからいいよーって書いてあるけど、そもそもdynamic_castしなくてもいいように実装すべきじゃないかなーとか思ったり。RTTIとかdynamic_castも遅いんだぜ。一応その辺りも補足してあるのはさすがです。

せっかく勉強したRTTIだけども、基本的にはあんまり使わないほうがいいから忘れちゃうかもなー。まぁ使わないに越したことはないんだけども。