2016-12-14 16 views
0

でオブジェクトを初期化し、次のC++コードを考えてみてください。このプログラムの出力はは、派生クラスのコンストラクタ

#include <iostream> 

using std::cout; 

class A 
{ 
public: 
    int a; 

    A():a(0) 
    { 
     cout << "A constructor\n"; 
    } 

    virtual void f() 
    { 
     cout << "f inside A\n"; 
    } 
}; 

class C : public A 
{ 
public: 
    int c; 

    virtual void f() 
    { 
     cout << "f inside C\n"; 
    } 

    C():c(0) 
    { 
     cout << "C constructor\n"; 
    } 
}; 

int main() 
{ 
    A varA = C(); 

    cout << "Size of C class: " << sizeof(C) << "\n"; 
    cout << "Size of varA object: " << sizeof(varA) << "\n"; 

    C* varC = static_cast<C*>(&varA); 
    varC->f(); 

    cout << "varC->a is " << varC->a << "\n"; 
    cout << "varC->c is " << varC->c << "\n"; 
} 

を:

A constructor 
C constructor 
Size of C class: 16 
Size of varA object: 8 
f inside A 
varC->a is 0 
varC->c is 1726166356 

IクラスCのコンストラクタとvarAオブジェクトを初期化します。 AクラスとCクラスのコンストラクタが呼び出されますが、varAは単にAオブジェクトです。私はvarAのアドレスをC*タイプにキャストし、そのf()関数を呼び出そうとしますが、それはAf()関数を出力するので、それを呼び出すための初期バインディングメカニズムを使用していると推測します。 派生クラスのコンストラクタを呼び出すと、このように、基本コンストラクタを呼び出した場合、同じオブジェクトが取得されると思います。 私は唯一の違いは、他のコンストラクタが呼び出されると思います。私の想定は正しいのですか、それとも他の違いがありますか?

+0

をなぜあなたはC(またはC *)のインスタンスをキャストしていますか?あなたが持っているのは、Aのインスタンスです。あなたの 'static_cast'呼び出しは許可されていない/定義されていないと思います。 –

+0

私はAとCをキャストしてbとcのメンバーをチェックしました。 – Radioga

+1

@Dag - 問題は、 'A'は' A 'なので、 'b'と' c'を持っていないということです。 'C'値から代入するときは、' A'部分を[スライスオフ](http://stackoverflow.com/questions/274626/what-is-object-slicing)し、残りの 'C'部分は破棄しますオブジェクト。 –

答えて

4

スライシングの古典的な例。 A varA = C();は、静的および動的タイプのオブジェクトであるAを残します。その結果、C* varC = static_cast<C*>(&varA);は未定義の動作を示します。

1

ただし、基本クラスのポインタで、完全な派生クラスを保存することができます:

int main() {   
    A* varA = new C(); 
    C* varC = static_cast<C*>(varA); 
    varC->f(); 

    cout << "varC->a is " << varC->a << endl; 
    cout << "varC->b is " << varC->b << endl; 
    cout << "varC->c is " << varC->c << endl; 
} // oops, forgot to delete varA/varC, memory leak! 
関連する問題