1

dynamic_cast通常、基本クラスのポインターがあり、それを派生クラスにダウンキャストする場合に使用されます。例えば、

class A
{
      public:
      virtual void foo();
};

class B : public A 
{
      public:
      void foo();
};

main()
{
    A* a = new B();
    B* b = dynamic_cast<B*> (a);
}

C-styleただし、キャストを使用して同じことを達成することもできます。

B* b = (B*)a;

それで、私の質問は、この演算子を使用することが完全に必要になる、つまり他に選択肢がない状況/ケースは何ですか?

4

5 に答える 5

4

ただし、C スタイルのキャストを使用して同じことを達成することもできます。

いいえ、できません:)

定義により、C スタイル キャストは一連のconst_caststatic_cast、およびreinterpret_cast1を実行して目的のキャストを実行しようとしますが、 は実行しません dynamic_caststatic_castしたがって、本質的に、ここでの C スタイルのキャストは、実際の動的な型が一致しない場合に未定義の動作をする a と同等です(逆に、この状況では、動的キャストはnullptrポインターの場合は返されstd::bad_cast、参照の場合はスローされます)。

つまり、正しい型にキャストしていることが確実なstatic_cast場合は、 (または C スタイルのキャストですが、個人的には好きではありません) を使用します。しかし、確信が持てない場合は、dynamic_cast

1 C スタイル キャストを使用して、プライベート ベースにキャストすることもできます。これは、前述の一連の C++ スタイル キャストでは実行できません。

于 2013-07-11T15:54:18.837 に答える
2

aタイプのオブジェクトへのポイントがB dynamic_castnullポインターを返すことを実際に知らない場合、状況を確認してそれに応じて処理できます。C スタイルのキャストではポインタを取得しますが、それを使用しようとすると未定義の動作が発生します。

于 2013-07-11T15:51:04.607 に答える
2

C スタイルのキャストよりも dynamic_cast を使用する必要がある場合の質問の場合、答えは常にです (つまり、C スタイルのキャストと dynamic_cast のどちらかを選択する必要がある場合は、常に dynamic_cast を優先します)。

ただし、一般的には、C++ で C スタイルのキャストを使用しないように努めてください。ツールでそれらを見つけるのは難しく (そのツールがコンパイラでない限り)、リファクタリングするたびにキャスト (バグの原因) を探して明示的に読み取らなければならないコードにつながります。

あなたの質問が、それを必要としないデザインで dynamic_cast をいつ使用すべきかということであれば、答えはほとんどありません。一般に、実装でポインターまたは参照をダウンキャストする必要がある設計は避ける必要があります。実装でダウンキャストを余儀なくされる場合、それはほとんどの場合、設計が不十分であることを示しています (つまり、正しい解決策はおそらくダウンキャストではなくリファクタリングです)。

于 2013-07-11T15:51:49.043 に答える
1

上記の回答のいくつかに追加すると、事実を無視しても、//キャストdynamic_castの代わりに c++ コードで c スタイルのキャストを使用することは本当に危険です。staticconstreinterpret

キャスト時に表示される内容によっては (ヘッダー ファイルが削除された場合などに変更される可能性があります)、C スタイルのキャストではポインター演算が正しく行われず、ガベージ ポインターが残る可能性があります。

ヘッダー ファイルの追加や削除によってコードの意味が変わることは決してありません。C++ キャストにはこの問題はありません。コンパイラが何をすべきかを判断できない場合、コンパイルの失敗が発生し、c スタイルのキャストで発生する可能性のあるランダムなランタイム クラッシュは発生しません。

于 2013-07-11T16:14:05.437 に答える
0

dynamic_cast が異なる (そして正しい) 結果を返す状況の 1 つは、左端以外の基本クラスからキャストしている場合です。

class A { 
public:
   int x; 
}

class B {
public:
   virtual void foo();
};

class C : public A, public B
{
     public:
     void foo();
};

main()
{
   B* b = new C();
   C* c = dynamic_cast<C*>(b);
}

C スタイルのキャストは、ここで間違ったポインタを返します。

于 2013-07-11T16:49:59.333 に答える