2011-07-19 9 views
0

仮想デストラクタが必要であることはわかっています。実行時の多態性におけるコンストラクタの振る舞い

Base *bptr = new Derived(); 
delete bptr; 

派生クラスオブジェクトは、基本クラスのポインタによって指し示され、オブジェクトが範囲外になるとデストラクタが仮想でない限り、唯一の基本クラスのデストラクタが呼び出される場合。

この場合、どのようにコンストラクターが正しく動作するのでしょうか。 BaseポインタがDerivedオブジェクトを指しているので、Baseコンストラクタだけが呼び出されているはずです。どのように派生クラスのコンストラクタを適切に呼び出すのですか?

私は理由を説明してください。

+0

"デストラクタが仮想でない限り、派生クラスオブジェクトがベースクラスポインタによって指し示され、オブジェクトがスコープから外れると、Baseクラスデストラクタだけが呼び出されます。 - 派生クラスのオブジェクトが有効範囲外になると、派生クラスのデストラクターが呼び出され、オブジェクトへの他の通常ポインターの存在とタイプは関係ありません。スコープの外に出る通常のポインタがあれば、何も呼び出されません。スマートポインタはデストラクタを呼び出すことができます。その場合、仮想ディスパッチが実際に派生クラスのものであることを確認する必要があります。 'new X'にはスコープはありません。 –

+0

私は、 "delete bptr"が実行されると、デストラクタが仮想でない限り、Baseクラスのデストラクタだけが呼び出されると言っていました。 – user166002

答えて

2

newでオブジェクトを作成しているうちに、のオブジェクトの完全情報があります。

new Derived(); // static type is same as dynamic type 

ポインタを割り当てるLHS部分は無関係です。だからあなたはそのようなvirtualコンストラクタのためのメカニズムを必要としません。詳細は、Bjarne Stroustrupのページを参照してください。

deleteへのポインタを使用しているので、他の注意、virtualデストラクタが必要です。

delete bptr; // static type may not be same as dynamic type 
2

新しいDerived()にはどこでも基本クラスの参照がありません。それを無意味に割り当てることもできます。したがって、結果のポインタが割り当てられるものは、構築に影響しません。あなたは次のことを実行

2

Base *bptr = new Derived(); 

それはあなたが構築しているものだから、あなたは、Derivedクラスのnewオペレータを呼び出しています。

newによって返されたDerived*Base*に割り当てると、暗黙の操作であるポインタを単純にアップキャストします。

0

あなたはは、明示的Derivedのインスタンスを構築したいを言う:

Base *bptr = new Derived(); 

はタイプclass Derived場合は、オブジェクトを作成してください、その後にそのオブジェクトへのポインタを保存してください意味しますbptr。したがって、コンパイラはを推測または推測することはありませんです。オブジェクトclass Derivedとリークのオブジェクトを作成します

new Derived(); 

は、と比較してみてください。コンパイラは、ここで推測することも推測することもありません。これら2つのスニペットの唯一の違いは、前者はポインタを格納し、後者はポインタを格納しないことです。

関連する問題