2008-08-26 8 views
22

ダイナミックキャスティングを避けるべきであることがよく聞かれます。私はあなたによると、それが「良い使用」の例になるのだろうかと思っていましたか?ダイナミックキャストの「良い使い方」の例は何ですか?

編集:

はい、私はthat other threadの承知している:私は私の質問をしていることが最初の答えの1を読み込むとき、それは確かです!

+12

この質問のタイトルは、説明と正確に一致しません。 – bradtgmurray

答えて

0

現在のおもちゃプロジェクトでは、dynamic_castを2回使用しています。かつてはC++での多重ディスパッチの欠如(ダイナミックキャストの代わりに複数のディスパッチを使用できるビジタースタイルのシステム)と、特定のサブタイプを特別なケースにするために一度回避しました。

私の考えでは、これらはどちらも許容されますが、前者は少なくとも言語欠損に由来します。実際、これは一般的な状況かもしれないと私は思う。ほとんどのdynamic_cast(および一般的なデザインパターン)は、目的とする言語の欠陥ではなく、特定の言語の欠陥に対する回避策です。

0

これは、Cインタフェースを介してオブジェクトにハンドルを公開する際に、実行時の型安全性を確保するために使用できます。公開されたすべてのクラスを共通の基底クラスから継承させる。関数のハンドルを受け入れるときは、まずベースクラスにキャストし、次に期待するクラスに動的キャストします。彼らが非官能的なハンドルを渡した場合、実行時にrttiが見つからない場合は例外が発生します。彼らが間違った型の有効なハンドルを渡した場合は、NULLポインタを取得し、独自の例外をスローすることができます。彼らが正しいポインタを渡したら、あなたは良いことです。 これは誤りではありませんが、間違ったハンドルを渡すとデータが不思議に壊れるまで、ハンドルからの直接の再解釈キャストよりも、間違った呼び出しをライブラリーにキャッチするほうが確かに優れています。

1

ここに私が頻繁に行うことがありますが、それはかなりではありませんが、シンプルで便利です。

私はよく がContainerInterfaceは、基本的な有用なものを持っているが、それがすべてです

template<class T> 
class MyVector : public ContainerInterface 
... 

のようなものを想像し、インターフェイスを実装するテンプレートのコンテナで動作します。テンプレートの実装を公開せずに整数のベクトルに特定のアルゴリズムを必要とする場合は、実装でインターフェイスオブジェクトを受け入れ、dynamic_castをMyVectorに渡すと便利です。例:

// function prototype (public API, in the header file) 
void ProcessVector(ContainerInterface& vecIfce); 

// function implementation (private, in the .cpp file) 
void ProcessVector(ContainerInterface& vecIfce) 
{ 
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a 
    // more complex method to choose which low-level implementation 
    // to use, basically rolling by hand your own polymorphism. 

    // Process a vector of integers 
    ... 
} 

私はポリモーフィックに解決されるだろうContainerInterfaceにprocess()メソッドを追加することができますが、それはよりよいOOPの方法だろうが、私は時々、このようにそれを行うことを好みます。単純なコンテナ、多くのアルゴリズムがあり、実装を隠しておきたい場合、dynamic_castは簡単で醜い解決策を提供します。

また、ダブルディスパッチ手法を参照することもできます。

HTH

0

これはC#の拡張メソッドでうまくいくでしょう。

たとえば、オブジェクトのリストがあり、それらからすべてのIDのリストを取得したいとします。私はそれらをすべて踏み出して取り出すことができますが、再利用のためにそのコードを分割したいと思います。

はそう

List<myObject> myObjectList = getMyObjects(); 

List<string> ids = myObjectList.PropertyList("id"); 

のようなものは、あなたが来ているタイプを知ることができません拡張メソッドを除いてクールになる。

ので

public static List<string> PropertyList(this object objList, string propName) { 
    var genList = (objList.GetType())objList; 
} 

は素晴らしいだろう。

9

この最近のスレッドは、どこに便利なのかを示しています。基本シェイプクラスとそれから派生したクラスCircleとRectangleがあります。平等のテストでは、サークルを長方形と等しくすることはできず、それらを比較しようとすると災害になることは明らかです。 Shapeへのポインタのコレクションを繰り返しながら、dynamic_castは、形状が匹敵するかどうかを伝え、比較を行うための適切なオブジェクトを与えてくれます。

Vector iterator not dereferencable

0

しかし、それはすぎ便利です時間のほとんど、非常に便利です:仕事を得るための最も簡単な方法を行っている場合は、dynamic_castのを行うことです、それは少なからずの症状です予期しない方法で将来的にトラブルにつながる可能性があります。

関連する問題