8

dynamic_castクラス階層全体で「クロスキャスト」を行うために使用することは合法であることを私は知っています。たとえば、次のようなクラスがある場合:

  A   B
   \ /
    C

A*タイプのオブジェクトを指すポインタがある場合はC、次を使用できます。

A* aPtr = /* ... something that produces a C* ... */
B* bPtr = dynamic_cast<B*>(aPtr);

私が指しているBベースオブジェクトへのポインタを取得します。C

C私がこれに言及する理由は、私が上記のコードを書いている時点で、コンパイラーがの定義を見たとしても、それがまだ見られていない可能性があるためAですBAこれは、コンパイラがとの間の接続を検出しない可能性があることを意味しますが、クラスが存在し、ある状況下で成功するB可能性があるため、とにかくコードをコンパイルする必要があります。Cdynamic_cast

問題は、これは、間違ったタイプのオブジェクトに誤ってクロスキャストする可能性があることを意味します。次のようなクラスがあるとします。

A   B    D
 \ /   
  C

ここに、Dいくつかのランダムな無関係のクラスがあります。私がこのようなものを書こうとすると:

A* aPtr = /* ... get a C* pointer ... */
D* dPtr = dynamic_cast<D*>(aPtr);

dynamic_castに接続する方法がないため、これは実行時に常に失敗します。を使用するつもりだったために誤って使用した場合、コンパイラは、意味のないキャストがあることをまったく示しません。ADDB

私の質問は、キャストが実行時に常に失敗することをコンパイラに警告させる方法はありますか? 言語レベルのソリューション、またはこれを検出できる主要なコンパイラーのコンパイラー設定に満足しています。外部ツールがある場合は、それでも問題ありません。このクラスのエラーをキャッチできるかどうかを知りたいだけです。

4

3 に答える 3

3

コンパイル時にこれを検出することはできません。関係を導入するクラスCは、まだ作成されていない動的にロード可能なライブラリで見つけることができ、コンパイラはそれ以外のことを証明できません。

ただし、いくつかの例外がある場合があります。プライベートコンストラクタ(またはプライベートデストラクタ)しかない場合A、コンパイラは、によってフレンドとして指定されていない新しいサブクラスがないことを確認できますA

于 2011-03-16T06:15:59.910 に答える
0

これが動的キャストの全体的な意味です。動的です。つまり、コンパイル時ではなく実行時にチェックされます。

コンパイラは、キャストされたクラスがポリモーフィックであるかどうかのみをチェックします。クラスがポリモーフィックでない場合、実行時にキャストをチェックするための十分な情報がありません。

そして最後に、動的キャストの後、プログラムは受信したポインタがnullでないかどうかをチェックする必要があります。参照にキャストする場合は、std::bad_castをキャッチする必要があります。

于 2017-04-04T09:57:40.210 に答える
-3

真実は、dynamic_castクラスが互いに関連していない場合でも、使用すると、任意のポリモーフィック型ポインターを任意のポリモーフィック型ポインターにキャストできるということです。

コンパイル時のチェックが必要な場合は、他のキャスト(static_castまたは暗黙の変換)を使用する必要があります。これは、多くの場合、他の理由で適さない可能性があります。

必要なときに使用するソリューションは、nullポインターが取得された場合に例外dynamic_castを実行し、スローするテンプレート関数です。dynamic_castもちろん、これは実行時チェックのみですが、かなり信頼性があります。

于 2011-03-16T06:15:39.490 に答える