2

次のコードがあります。

using namespace std;

class BaseOk
{
public:
    virtual void ImplementMe()
    {
    };
};
class DerivedOk : public BaseOk
{
public:
    void ImplementMe()
    {
    }
};

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



int main() 
{ 
    CBase b; CBase* pb;
    CDerived d; CDerived* pd;

    pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
    pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived  -> this doesn't compile

    // Polymorphic case

    BaseOk b2; BaseOk* pb2;
    DerivedOk d2; DerivedOk* pd2;

    pb2 = dynamic_cast<BaseOk*>(&d2);     // ok: derived-to-base
    pd2 = dynamic_cast<DerivedOk*>(&b2);  // wrong: base-to-derived -> this returns a NULL pointer

}

ポインター「pd」を含む行はダウンキャストを実行しますが、結果がまったく異なるオブジェクトであるため、失敗することに同意します。私の質問は、NULL ポインターを返すだけでなく、その行の dynamic_cast がまったくコンパイルされないのはなぜですか?

MSVC2012 コンパイラを使用しています

4

2 に答える 2

2

dynamic_castNULL ポインターを返すだけでなく、その行の がまったくコンパイルされないのはなぜですか?

これは制限ではなく機能/機能と考えてください。

dynamic_castポインター/参照に基づいてオブジェクトの RTTI (ランタイム型情報) を見つけるメカニズムです。
ここで、クラスがまったくポリモーフィックでない (つまり、virtualメソッドを含まない) 場合、間違いなく常に失敗するdynamic_castとします。 つまり、合格の可能性が 0 の場所を使用する必要はありません。コンパイル時にわかっていることでマシンサイクルを浪費する必要があるのはなぜですか? そのため、コンパイラはすぐに機能を提供します。
dynamic_cast

これにはもう一つ隠れた利点があります。参照を使用dynamic_castしているとします。失敗すると、例外がスローされます。コンパイル時にすでにわかっている例外を処理したいと思う人はいるでしょうか!

于 2013-03-14T12:12:12.707 に答える
2

dynamic_cast非ポリモーフィック型へのポインターで使用するとエラーになります。これは診断可能なルールであるため、コンパイル時にエラーが発生するはずです。

ターゲット型に変換できないポリモーフィック型へのポインターで使用してもエラーにはなりません。また、コンパイル時に一般的に検出されることはありません。明確に定義された動作を持ち、null ポインターを提供します。

于 2013-03-14T12:12:49.623 に答える