4

私のプロジェクトでは、次のようなシナリオがあります。

  • 1) BaseClass は、親クラス IFlow から派生するインターフェイスです。
  • 2) ChildClass はそれから派生します。つまり、Base クラスから派生します。
  • 3) childClass Init 関数dynamic_castでは、以下に示すように、IFlow のオブジェクトを BaseClass にキャストするために使用しています。

    void ChildClass::init()
    {    
        IFlow* pFlow = someMethod(); //it returns the IFlow object pointer
    
        //this works for static cast but fails for dynamic cast    
        BaseClass *base =  dynamic_cast<BaseClass*>(pFlow) ;
    } 
    

上記のコードでは、 の 2 行目dynamic _castは 0 を返しますが、dynamic_castが に変更されたstatic_cast場合、コードは期待どおりに機能します。ご意見をお聞かせください

4

4 に答える 4

8

dynamic_cast次の 2 つの場合は「機能しません」。

  1. RTTI を使用せずにコードをコンパイルしました。コンパイラの設定を修正します。

  2. の全体的な目的は、キャストが実際に機能することdynamic_cast確認することです。子から親へのキャストは常に機能します。これは、あるタイプのすべての子がそのタイプであることが保証されているためです (「すべての犬は動物ですが、すべての動物が犬であるとは限りません」ということ)。オブジェクトが実際にその子の型でない場合、親から子へのキャストは失敗する可能性があります。指定した が実際には でないdynamic_cast場合、 は null ポインタを返します。IFlowBaseClass

    さらに、あなたはうまくいきstatic_castません。単純に値を返します。使用すると、未定義の動作が発生する値。したがって、使用を試みることができる値を返したという意味でのみ「機能」します。

したがって、これら2つのことのうちの1つが起こりました。の実装を提供してくれなかったので、どれを見つけるかはあなた次第ですsomeMethod

于 2012-07-02T08:09:19.517 に答える
1

キャストが正当でない場合、 Adynamic_cast<>は null (ゼロ) を返します。この場合、それはあなたが望むことをしています: 継承ツリーのどこかに問題があります。( static_cast<>「動作」するのは大ハンマーだからです。実行時にポインターが実際に持つ型を知らなくても、コンパイル時にキャストを強制します。)

于 2012-07-02T08:08:21.200 に答える
1

このような場合は?:

class A
{
public:
    A(){a = 0;};
    virtual ~A(){};
protected:
    int a;
};
A *GetAInstance();

class B : public A
{
public:
    B() : A() {b = 1;};
    virtual ~B(){};
protected:
    int b;
};

class C: public B
{
public:
    C() : B() {};
    ~C(){};

    void CheckA()
    {
        A *pA = GetAInstance();
        B *pB = dynamic_cast<B*>(pA);  --> Here pB is NULL.
        B *pB2 = static_cast<B*>(pA);
    };
};

A *GetAInstance()
{
    A *pA = new A();
    return pA;
};

int _tmain(int argc, _TCHAR* argv[])
{
    C *pC = new C();
    pC->CheckA();
    return 0;
}

これは、親ポインターをその子ポインターに設定しようとしているためです。dynamic_cast では、安全ではないと考えられるため、子ポインターを NULL に設定します。上の pB が NULL であることがわかります。子クラスにはさらに多くの関数/メンバー変数がある可能性があるため、これらの新しい関数/メンバー変数を呼び出すと、実行時エラーが発生します。しかし、 static_cast はこれを気にしません。これはコンパイラの時間チェックであり、実行時間のチェックではありません。static_cast は、何らかの関係があるかどうかのみを気にします。持っている場合、 static_cast は実行時エラーを気にせずにポインターを変換します。この小さなサンプルを実行して、pB2 が NULL でないことを確認してください。:)

役に立つことを願っています。ありがとう!:)

于 2012-07-02T08:25:44.747 に答える
0

someMethod() によって返される型は何ですか? dynamic_cast を機能させるには、BaseClass から派生させる必要があります。正しいタイプでない場合、下向きにキャストすることはできません。

静的キャストはコンパイル時に機能し、コンパイラはポインターを単に反転します。

于 2012-07-02T08:03:28.050 に答える