C++ のキャスト - dynamic_cast

今回は C++ のキャスト dynamic_cast について考えてみます。


C++ の 4 つのキャストのうち、 dynamic_cast 以外はもともと C でできるキャストを用途別に名前をつけただけなのですが、 dynamic_cast だけは C++ 特有のキャストです。
これは ダウンキャスト とも呼ばれるもので、基本型のポインターを派生型のポインターに変換する時に使うキャストです。

多様性

C++ のキモに多様性があります。例えば以下のような関係のクラスがあったとします。

class_figuire.png

Figuire クラスから各種の図形クラスが継承されています。 アプリケーションでは実際には Rect, Line などのオブジェクトを持っているのですが、それらを統一して扱うため、 抽象 クラスの Figuire 型としてオブジェクトのポインターを使います。

Figuire クラスのポインターから仮想関数 draw() を呼び出したとします。 多様性は、 Figuire クラスの draw() ではなく、実際のクラスの draw() が呼び出されるというものです。
これは Figuire 型のポインター を vector などにいれ、ループで回したりして使います。
for (itr = figs.begin() ; itr != figs.end() ; itr++)
{
    (*itr)->draw();
}
これを C で書こうとすると union などで統一したデータに入れることは出来ますが、 描画処理は対象ごとにわけないといけないので switch 文の山となります。 そのため、新しい図形クラスを追加した場合などあちこち修正する必要があります。

アップキャスト

多様性を使うため、Rect 型などの実際の具象クラスのオブジェクトのポインターを抽象 Figuire クラスのポインターに代入する必要があります。ここで発生するキャストはアップキャストと呼ばれます。
Figuire *fig = new Rect();
型の変換が起こりますが、キャストを明示的に示す必要はありません
Figure クラスでできることは必ず Rect クラスでもできるので安全ですし、多様性は C++ のキモの一つですので、コンパイラーは「当然このような使われ方はする」と思ってます。

ダウンキャスト(dynamic_cast)

アップキャストに対して、逆の Figure から Rect に変換するダウンキャストは危険です。
Rect *rect = dynamic_cast<Rect *>(somefig);
Figure クラスのポインター somefig の指す実態は Rect のオブジェクトかも知れませんし、 Line のオブジェクトかも知れません。 そのため、明示的にキャストを記述する必要があります


この際、 dynamic_cast を使っていると本当に Rect クラスのオブジェクト以外の場合は rect には NULL が入ります。
この dynamic_cast は安全にキャストしてくれるいいものなのですが、 「dynamic_cast は使うな」と言われています。

dynamic_cast を避ける理由

何故 dynamic_cast を避けるべきかというと、 そもそも抽象クラスのオブジェクトを具象クラスのオブジェクトを入れるダウンキャスト自体がよくありません。

dynamic_cast でキャストして処理を分けるのは、 C の switch 文で型別に処理を振り分けているようなものです。
これを避けるための多様性なので、 dynamic_cast で行う処理は仮想関数を使って記述するべきです。 dynamic_cast が必要な場合には「設計をまちがったかな」と思った方がいいでしょう。


このような話は『 Efefective C++ 』の 27 項に詳しく書かれているので、興味ある方は読んでみてください。

Effective C++ 原著第 3 版 (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)Effective C++ 原著第 3 版 (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
(2006/04/29)
スコット・メイヤーズ

商品詳細を見る
関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
43位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
3位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

05月 | 2017年06月 | 07月
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。