VC++2008のキャスト演算子(その1)
C++で分かりにくいのがキャスト演算子(static_cast/dynamic_cast/reinterpret_cast/const_cast)の使い分けである。
手元にあるC++の教科書「C++ 実践プログラミング」(Steve Oualline著 オライリー)は600ページぐらいあって単なる入門書ではないが、キャスト演算子の違いについて詳しく書いていない。
以下は復習を兼ねてのメモ書きです。(その1)ではstatic_castとdynamic_castとの区別。
「C++ 実践プログラミング」を資料1、「Boost C++をチューンアップする最先端ライブラリ」(ビョルン・カールソン(著) 村上雅章(訳) ピアソン・エデュケーション)を資料2、として参照している。
使用したVC++は「Visual C++ 2008 Express Edition SP1」
[1] テストプログラム
class A {
public:
virtual void a(){cout<<"A\n";}
};
class AA : public A {
public:
void aa(){cout<<"AA\n";}
};
class AB : public A {
public:
void ab(){cout<<"AB\n";}
};
A* a = new A();
A* aa = new AA();
A* ab = new AB();
static_cast<AA*>(aa)->aa(); // (1)
static_cast<AA*>(ab)->aa(); // (2)
dynamic_cast<AA*>(aa)->aa(); // (3)
dynamic_cast<AA*>(ab)->aa(); // (4)
[1-1] プロジェクトのプロパティ「ランタイム型情報を有効にする」を「いいえ(/GR-)」に設定したとき、(3)(4)でコンパイル時警告(warning C4541)は出るが、とりあえずコンパイルは正常終了する。
実行してみると、
・ (2)が実行できる。クラスAAのメンバー関数aa()が実行される。(これは結構すごい!)
・ (3)がランタイムエラーとなる。(プログラムを作った本人は、変数aaがAAのオブジェクトを保持していることに自信?があるのですけど)
[1-2] プロジェクトのプロパティ「ランタイム型情報を有効にする」を「はい(/GR)」に設定したとき、コンパイル時警告は無い。
実行してみると、
・ (1)(2)(3)(4)すべて実行できる。しかも、クラスAAのメンバー関数aa()が実行される。
・ (2)はともかく(4)が実行できてしまうのは何のためのランタイム型情報でdynamic_castなのだろうか。
[2] クラスAAだけ定義を変えた。
class AA : public A {
int aai;
public:
void aa(){ cout<<"AA"<<aai<<"\n"; }
AA() { aai = 1; }
};
[2-1] ランタイム型情報を有効にして実行してみると、
・ (1)(3)は期待通りの動きをする。
・ (2)はやはり実行できるが、aaiの値としてメチャクチャな値を使っている。static_castが危険であるといわれるのはこのあたりにあるのだろう。
・ (4)はランタイムエラーとなる。これが(自分の理解では)本来のdynamic_castの動きである。
・ (2)と(4)の動きの違いがstatic_castとdynamic_castとの違いなのだろう。
[2-2] (4)のランタイムエラーについて。文献1は「不正な変換を試みると、例外がスローされ」(P434)としているが、文献2は「ポインタ型に対してdynamic_castが用いられ、変換に失敗した場合にはnullポインタが返される」(P52)としています。
C++の規格としてはどちらが正しいかは分かりませんが、(4)に関して言うと文献2の動きをしています。dynamic_cast自体は例外をスローせず、nullポインタを返しています。
« VC++2008のRegex | トップページ | VC++2008のキャスト演算子(その2) »
「パソコン・インターネット」カテゴリの記事
- トップページにTooltip (jQueryを使ったオリジナル)(2008.12.20)
- JAVAのハッシュテーブル HashMap(2008.12.15)
- C#のハッシュテーブル Dictionary(2008.12.15)
- C++/C#/JAVA コレクション比較 【ハッシュテーブルの比較概要】(2008.12.12)
- C++/C#/JAVA コレクション比較 【インデックスによる要素アクセス】(2008.12.10)
コメント