2016-09-20 8 views
0
#include <iostream> 
using namesapce std; 
class A 
{ 
    public: 
     virtual ~A(){cout<<"delete A"<<endl}; 
}; 
class B: public A 
{ 
    public: 
     B(int n):n(n){} 
     void show(){cout<<n<<endl;} 
     ~B(){cout<<"delete B"<<endl;} 
    private: 
     int n; 

} 
int main() 
{ 
    A *pa; 
    B *pb = new B(1); 
    pa = pb; 
    delete pa; 
    pb->show(); 
    return 0; 
} 

calss Aのデストラクタがvirtual ~A(){...}、プログラムの出力である: delete B delete A 1 クラスAのデストラクタが~A(){...}、progarmの出力である: delete A 0 nの値が異なる理由、場合クラスAのデストラクタは仮想または非仮想ですか?オブジェクトを破壊するためにBの呼び出しのデストラクタ、なぜCalssメンバnが存在するのですか?なぜクラスAのデストラクタが仮想または非仮想である場合、Bのcalssメンバnの値が異なるのですか?

+0

「仮想」機能は何ですか? – Barry

+1

'pb-> show(){};'とは何ですか? – AnT

+0

あなたはこれを読むことができますhttp://www.learncpp.com/cpp-tutorial/122-virtual-functions/ –

答えて

1
A *pa; 
B *pb = new B(1); 
pa = pb; 

これはアップキャスティングと呼ばれます。アップキャストが行われるたびに、基本クラスのデストラクタを仮想化する必要があります。

仮想基底destructiorがなければ、delete paは、派生クラスオブジェクトが決して破棄されずメモリリークが発生するため、望ましくない基本クラスのデストラクタのみを呼び出します。

基本クラスの仮想デストラクタは、最初の派生クラスのデストラクタを呼び出し、それが望ましい動作であり、アップキャストのためにリークを引き起こさない自身を破壊します。

+0

つまり、仮想基本クラスのデストラクタがなければ、_undefinedビヘイビアが得られます。 – qxz

+0

なぜnの値が違うのですか? – PengWin

+0

wahtは定義されていない動作です、なぜコンパイラにコーダにエラーがありますか? – PengWin

1

プログラムは未定義の動作を示します。それはあなたの「なぜ」の質問に対する唯一の答えです。

最初に、Aのデストラクタが仮想でない場合、delete paをコード内で実行すると、定義されていない動作が発生します。親タイプA *へのポインタを介してタイプBdeleteオブジェクトを試行すると、デストラクタの定義されていない動作がAになります。これは仮想ではありません。

第2に、pb->show()は、既に破壊されたオブジェクトのメソッドを呼び出す試みのようです。デストラクタが仮想であるかどうかにかかわらず、動作は未定義です。

関連する問題