2009-08-14 8 views
33

dynamic_castの動作を確認していましたが、失敗した場合、宛先が参照型の場合にのみstd :: bad_cast例外がスローされます。デスティネーションがポインタ型の場合、キャストから例外はスローされません。これは私のサンプルコードです:参照とポインタでdynamic_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を使用してコンパイルされます。これは正しい動作ですか?はいの場合は、なぜ違いがありますか?

答えて

59

はい、これは正しい動作です。その理由は、null参照ではなくヌルポインタを持つことができるからです。すべての参照をオブジェクトにバインドする必要があるからです。

ポインタタイプのdynamic_castが失敗した場合、ヌルポインタを返し、呼び出し側がそのポインタを確認できますが、参照型に失敗した場合はnull参照を返すことができないため、唯一の合理的な方法です問題を伝える

5

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

つまり、参照をNULLにすることはできません。したがって、戻すのに適したものはありません。

+1

しかし、ポインタの場合でも例外がスローされないのはなぜですか? – Naveen

+1

これで、ダーティコードであるすべてのdynamic_castを試してみる必要があります。代わりに、アドレスを取ってdynamic_cast itとヌルをチェックすることができます。 – sharptooth

+0

また、例外をスローしてキャッチするのは比較的高価です。デザイナーは、そのコストを最小限に抑える方法を見つけたいと思っています。 –

8

はい、5.2.7/9

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

18

C++規格、セクション5.2.7/9参照:

9が失敗 ポインタ型にキャストの値が必要な結果型のヌルポインタ値 あります。失敗した 参照型へのキャストはbad_cast (18.5.2)をスローします。理由として

- これらはD & E帳からStroustrup氏の言葉です、セクション14.2.2:私は がチェック参照型について 仮定をしたいとき

Iが基準キャストを使用し、私が間違っていると仮定して、それが失敗したと考えてください。 代わりに の代わりに の中から選択したい場合は、ポインタキャストを使用して の結果をテストします。

+1

標準とStroustrupの解釈の両方を関連づけるために、この答えの余分な作業を感謝します。 –

関連する問題