継承階層をトラバースするための静的キャスト対動的キャスト

c++ casting dynamic-cast rtti static-cast

静的キャストを使用して継承階層をナビゲートする方が動的キャストを使用するよりも効率的であると言及しているCに関するある本を見ました。

例:

#include #include

名前空間stdを使用する。

クラスShape {public:virtual〜Shape(){}; ;クラスCircle:public Shape {};クラスSquare:public Shape {};クラスOther {};

int main(){円c;

形状* s =

//より明示的だが不要:s = static_cast(

円* cp = 0;平方* sp = 0。

//クラス階層の静的ナビゲーションは追加の型情報を必要とします// if(typeid(s)== typeid(cp))// C RTTI cp = static_cast(s); if(typeid(s)== typeid(sp))sp = static_cast(s); if(cp!= 0)cout << "それは円です!" << endl; if(sp!= 0)cout << "それは正方形だ!" << endl;

//静的ナビゲーションは効率の悪さだけです。 // dynamic_castは常に安全です。 ただし、// Other * op = static_cast(s); //その他* op2 =(その他*); //エラーメッセージを表示すると便利です。 //しません} ///:〜

ただし、動的キャストと静的キャストの両方(上記で実装されているように)は、そのようなナビゲーションが機能するためにRTTIを有効にする必要があります。 動的キャストではクラス階層が多態性である必要があるということです。 少なくとも1つの仮想関数を持つ基本クラス) 静的キャストのこの効率の向上はどこから来たのでしょうか。 この本は、動的キャストが型保証されたダウンキャストを行うための好ましい方法であると述べています。

  5  2


ベストアンサー

`static_cast`それ自体* RTTIは必要ありません – ` typeid`は( `dynamic_cast`と同様に)持っていますが、それは全く異なる問題です。 ほとんどのキャストは単にコンパイラに「私を信頼しています。自分がしていることを知っています」と言っているだけです – `dynamic_cast`は例外です。 それがパフォーマンスの大きな違いです。

9


可能であれば、型を切り替えないようにするほうが_はるかに良いです。 これは通常、関連するコードを、サブタイプごとに異なる方法で実装された仮想メソッドに移動することによって行われます。

クラスShape {public:virtual〜Shape(){}; virtual void announce()= 0。 //同様にCircle and Squareで再宣言します。 ;

void Circle :: announce(){cout << "サークルです!" << endl; }

void Square :: announce(){cout << "これは正方形です! << endl; }

// Later...
s-> announce();

変更できない既存の継承階層を使用している場合は、型切り替えのより拡張可能な代替方法について Visitorパターンを調べてください。

より詳しい情報: static_cast`はRTTIを必要としませんが、それを使用したダウンキャストは安全ではない可能性があり、未定義の動作(例えば、 クラッシュ)。 `dynamic_cast`はRTTI情報をチェックするので(したがって必要とするため)安全ですが遅くなります。 古いCスタイルのキャストは `static_cast`よりもさらに安全ではありません。なぜなら、 static_cast`はコンパイル時エラーでオブジェクト化することになる、完全に無関係な型に静かにキャストするからです。

7


静的キャスト(およびtypeidチェック)では、中間型にダウンキャストすることはできません(子は父から派生し、祖父から派生することはできません)。使用法はもう少し制限されています。 typeidチェックなしのstatic_castはパフォーマンスの正しさを犠牲にしています、そしてあなたは彼らが言うことを知っています:

パフォーマンスの正確さを犠牲にする人はどちらにも値しません。

それから、もちろん、あなたはいくつかのCPU命令を必死に必要としているところや改善を探す場所が他にないところがあります、そしてあなたは自分がしていることに対して実際に安全です。パフォーマンスを向上させるには、dynamic_castの代わりにstatic_castを使用します。 それで、あなたはあなたがあなたのデザイン、あるいはあなたのアルゴリズムを作り直すか、より良いハードウェアを手に入れなければならないことを知っています。

rtti static_castを使用することによって課される制限は、このトリックを使用していたすべての場所を手直ししてほんの数CPU命令しか手に入れないで、後で新しい派生クラスでコードを拡張できないことです。 その手直し自体は、おそらくあなたが得たCPU時間よりも長い時間(より高いエンジニアリング時間)を要するでしょう。 いずれにせよ、ダウンキャストに費やされる時間が顕著である場合は、j_random_hackerが示唆するようにデザインを作り直すと、デザインとパフォーマンスの両方で向上します。

5


typeidチェックを行わずにキャストが成功しなかった場合、 `dynamic_cast`はNULLを返します。 `static_cast`は成功するでしょう(そして最終的なクラッシュのような未定義の振る舞いに導きます)。 それはおそらく速度差です。

1


タイトルとURLをコピーしました