5

このコードを見てみましょう:

class CBase
{
 public:
    virtual vfunc() { cout << "CBase::vfunc()" << endl; }
};

class CChild: public CBase
{
 public:
    vfunc() { cout << "CChild::vfunc()" << endl; }
};

int main() 
{
 CBase *pBase = new CBase;
 ((CChild*)pBase)->vfunc(); // !!! important 
 delete pBase;
 return 0;
}

出力は次のとおりです。

CBase::vfunc()

しかし、私は見たい: CChild::vfunc()

明示的な ((CChild*)pBase) キャストは、"CChild*" 型にキャストされます。では、派生した vfunc() を呼び出すには、「重要な」文字列を ((CChild*)pBase)->CChild::vfunc(); に置き換える必要があります。

4

4 に答える 4

6

それはそれがどのように機能するかではありません-これは次のとおりです。

CBase *pBase = new CChild;
pBase->vfunc();

virtual関数呼び出しは、ポインターと参照で動的に解決されます (メソッドを明示的に呼び出す場合を除きます)。つまり、ポインターが何であるかをコンパイラーに伝えても問題ありません。コンパイラーは vftable でメソッドを探します。あなたの場合、これはのvftableですCBase

于 2012-08-10T18:47:38.933 に答える
5

できません。 *pBaseタイプのオブジェクトですCBase。オブジェクト CChildではないため、のように扱うことはできません。CChild

キャストによって取得されたポインターを使用してCChild*、プログラムが未定義の動作を示すようにします。

于 2012-08-10T18:47:41.793 に答える
2

他の回答は重要な点を示しています-補足するために:実際にaを扱っている場合CChild(たとえば、パラメーターとして渡された参照である場合)、dynamic_castダウンキャストに使用できます。ただし、依存度が高いdynamic_castということは、多くの場合、設計が間違っていることを示しています。

キャストの詳細については、http: //msdn.microsoft.com/en-us/library/cby9kycs (v=vs.80).aspx を参照してください。

CBaseそのため、このプロセスではパラメータをCChildviaにキャストする必要がありますdynamic_cast。参照が でありCChilddynamic_cast成功した場合は、 a を扱っていることを確認でき、CChildそれを として安全に使用できますCChild

于 2012-08-10T18:52:28.923 に答える