2

私は C++ キャスト演算子を見直していますが、次の疑問があります。

ポリモーフィック クラス用

  • 使用する必要がありますpolymorphic_cast
  • static_castダウンキャストは未定義の動作を引き起こす可能性があるため、絶対に使用しないでください。とにかく、コードはこのケースをコンパイルします。

今、私が次の状況にあるとします

class CBase{};
class CDerived : public CBase{};

int main( int argc, char** argv ){
    CBase* p = new CDerived();
    //.. do something
    CDerived*pd = static_cast<CDerived*>( p );
}

ポリモーフィズムが含まれていないため、使用polymorphic_castしません。コードはコンパイルさえしません。

ある時点で、誰かvirtualが継承ツリーにいくつかの関数を導入し、私が今それを認識しているため、危険にさらされている場合: どうすればそれを実現できますか?

リスクを回避するために移動する必要polymorphic_castがありますが、コードは通知なしで引き続きコンパイルされます。

そのような変化を認識したり、これらのケースを防ぐために何をしますか?

ありがとうAFG

4

3 に答える 3

3

含めなかった背景 - ブーストには、キャストが失敗したときにスロー polymorphic_castされるラッパーがあります。データがキャスト先のタイプであることが確実な場合は問題ありません...仮想メンバーの有無にかかわらず問題はなく、コンパイルされないと言って含めたコードはコンパイルされ、次のように問題なく実行されますは。dynamic_cast<>static_cast<>

別の派生クラスに誤ってキャストする可能性について考えていると思いますか? それがキャスティングの有用性/危険性ですね。厳密に言えば、RTTI は 1 つ以上の仮想関数を持つ型でのみ使用できるため、仮想デストラクタを追加してから dynamic_cast<> を使用できます。

static_cast<> で記述されたコードは、仮想関数の導入に関係なく、同じ型を安全に処理し続けます...そのコードを他の型 (つまり、CDerived またはそこから派生したものではない) に渡し始める場合は、 dynamic_cast<> または互換性のない操作を防ぐためのその他の変更。

于 2010-10-25T08:46:05.177 に答える
1

(CBase *型の)ポインターpを処理している間、ポイントされたオブジェクトはCBaseとして扱われますが、すべての仮想関数は正しいことを行います。ポインターpdは、CDerivedと同じオブジェクトを扱います。この方法でのアップキャストは危険です。オブジェクトがアップキャスト型から派生していない場合、アップキャストされたオブジェクトの余分なメンバーデータが失われ(つまり、他のデータを調べてしまう)、仮想関数のルックアップが行われるためです。すべてが台無しになりました。これは、スライスする可能性のあるダウンキャスト(この質問にタグを付けた場合)とは逆です。

これを回避するには、プログラミングスタイルを変更する必要があります。同じオブジェクトを2つの異なるタイプとして扱うことは、疑わしい方法です。C ++は型の安全性を強化するのに非常に優れていますが、本当にやりたい場合や、よくわからない場合は、厄介なことを回避できます。オブジェクトタイプに応じて異なることを実行したいが、仮想関数(ダブルディスパッチなど)では実行できない場合は、RTTIをさらに詳しく調べる必要があります(ここを参照するか、ここでいくつかの良い例を参照してください)。

于 2010-10-25T09:01:50.197 に答える
0

polymorphic_cast は C++ では定義されていません。dynamic_cast について考えていますか?

とにかく、それを防ぐために何もすることはできません。

于 2010-10-25T08:42:48.470 に答える