50

dynamic_cast の動作を確認していたところ、失敗すると、宛先が参照型の場合にのみ std::bad_cast 例外がスローされることがわかりました。宛先がポインター型の場合、キャストから例外はスローされません。これは私のサンプルコードです:

class A
{
    public:
        virtual ~A()
        {
        }
};

class B : public A
{
};

int  main()
{
    A* p = new A;

    //Using reference
    try
    {
    B& b = dynamic_cast<B&>(*p);
    }
    catch(std::bad_cast exp)
    {
    std::cout<<"Caught bad cast\n";
    }

    //Using pointer
      try
    {
    B* pB = dynamic_cast<B*>(p);

    if( pB == NULL)
    {
        std::cout<<"NULL Pointer\n";
    }
    }
    catch(std::bad_cast exp)
    {
    std::cout<<"Caught bad cast\n";
    }

    return 0;
}

出力は「キャッチされた不正なキャスト」と「NULL ポインター」です。コードは VS2008 を使用してコンパイルされます。これは正しい動作ですか? はいの場合、なぜ違いがあるのですか?

4

4 に答える 4

84

はい、これは正しい動作です。その理由は、null ポインターは使用できますが、null 参照は使用できないためです。参照はオブジェクトにバインドする必要があります。

したがって、ポインター型の dynamic_cast が失敗すると null ポインターが返され、呼び出し元はそれを確認できますが、参照型で失敗した場合は null 参照を返すことができないため、問題を通知する唯一の合理的な方法は例外です。 .

于 2009-08-14T09:14:38.153 に答える
34

C++ 標準のセクション 5.2.7/9 を参照してください。

9 ポインター型への失敗したキャストの値は、必要な結果型のヌル ポインター値です。参照型へのキャストが失敗すると、bad_cast がスローされます (18.5.2)。

その理由については、D & E ブックのセクション 14.2.2 からの Stroustrup の言葉です。

参照型に関する仮定をチェックしたいときに参照キャストを使用し、仮定が間違っているため失敗と見なします。代わりに、もっともらしい選択肢の中から選択したい場合は、ポインターキャストを使用して結果をテストします。

于 2009-08-14T09:17:49.583 に答える
8

はい、5.2.7/9

ポインター型への失敗したキャストの値は、必要な結果型の null ポインター値です。参照型へのキャストが失敗すると、bad_cast がスローされます (18.5.2)。

于 2009-08-14T09:17:42.407 に答える
7

はい、そうです。dynamic_cast失敗した参照キャストに対して NULL を返すことはできないため、例外が唯一の解決策です。

つまり、参照を NULL にすることはできないため、返すのに適したものはありません。

于 2009-08-14T09:14:34.877 に答える