23

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

編集:

はい、私はその別のスレッドを知っています:私が質問したのは、そこで最初の答えの1つを読んだときです!

4

6 に答える 6

9

この最近のスレッドは、それが役立つ場所の例を示しています。基本の Shape クラスと、それから派生したクラス Circle および Rectangle があります。等しいかどうかのテストでは、Circle が Rectangle と等しくないことは明らかであり、それらを比較しようとすると大変なことになります。シェイプへのポインターのコレクションを反復処理する際、dynamic_cast は二重の役割を果たします。シェイプが比較可能かどうかを示し、比較を行うための適切なオブジェクトを提供します。

ベクトル反復子は逆参照できません

于 2008-11-19T20:47:11.910 に答える
1

これは私がよくすることです。きれいではありませんが、シンプルで便利です。

私はよく、インターフェイスを実装するテンプレート コンテナーを使用します。次のようなものを想像してください。

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

ContainerInterface には基本的な便利なものがありますが、それだけです。テンプレートの実装を公開せずに、整数のベクトルに特定のアルゴリズムが必要な場合は、インターフェイス オブジェクトを受け入れて、それを実装の MyVector に dynamic_cast すると便利です。例:

// 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
    ...
}

ポリモーフィックに解決される Process() メソッドを ContainerInterface に追加することもできます。これはより適切な OOP メソッドですが、この方法を好む場合もあります。単純なコンテナーと多くのアルゴリズムがあり、実装を隠しておきたい場合、dynamic_cast は簡単で醜いソリューションを提供します。

また、二重ディスパッチ手法も検討できます。

HTH

于 2008-09-22T19:59:27.240 に答える
0

私の現在のおもちゃプロジェクトはdynamic_castを2回使用しています。1回はC++での多重ディスパッチの欠如を回避するため(これはdynamic_castsの代わりに複数ディスパッチを使用できるビジタースタイルのシステムです)、もう1回は特定のサブタイプを特殊なケースにするためです。

私の見解では、前者は少なくとも言語の不足に起因しますが、これらは両方とも受け入れられます。実際、これは一般的な状況かもしれないと思います。ほとんどのdynamic_casts(および一般に非常に多くの「デザインパターン」)は、目的とするものではなく、特定の言語の欠陥に対する回避策です。

于 2008-08-26T13:55:34.993 に答える
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;
}

すごいでしょう。

于 2008-11-19T20:32:48.897 に答える
0

これは、C インターフェイスを介してオブジェクトにハンドルを公開するときに、実行時のタイプ セーフのために使用できます。公開されたすべてのクラスが共通の基本クラスから継承されるようにします。関数へのハンドルを受け入れるときは、まず基本クラスにキャストしてから、期待するクラスに動的にキャストします。無意味なハンドルが渡された場合、ランタイムが rtti を見つけられないときに例外が発生します。間違った型の有効なハンドルが渡された場合、NULL ポインターを取得し、独自の例外をスローできます。正しいポインターが渡された場合は、問題ありません。これは絶対確実というわけではありませんが、ライブラリへの誤った呼び出しをキャッチする場合は、ハンドルからキャストを直接再解釈して、間違ったハンドルを渡したときに一部のデータが不可解に破損するまで待機するよりも確かに優れています。

于 2008-09-19T17:55:47.420 に答える