2017-03-21 20 views
1

クラスBのオブジェクトを破棄したいとします。C++の仮想デストラクタから仮想メソッドを呼び出す

class A { 
public: 
    A() { 
     std::cout << "construct A" << av::endl; 
     a = new int; 
    } 
    virtual ~A() { 
     std::cout << "destruct A" << av::endl; 
     this->clear(); 
    } 
    virtual void clear() { 
     std::cout << "clear A" << av::endl; 
     delete a; 
    } 
protected: 
    int *a; 
}; 

class B : public A { 
public: 
    B() { 
     std::cout << "construct B" << av::endl; 
     b = new int; 
    } 
    ~B() { 
     std::cout << "destruct B" << av::endl; 
    } 
    void clear() override { 
     std::cout << "clear B" << av::endl; 
     delete b; 
     delete this->a; 
    } 
private: 
    int *b; 
}; 

そして、それはclear()メソッドでやりたいと思います。しかし、私は次のコードを実行すると:

A *a = new B(); 
delete a; 

を私が手:

はBが明確

そしてclear Bを破壊構築物Bの破壊を構築するには、印刷されることはありません。 私は何が間違っていますか?

答えて

5

非公式には、~A();では、B部分は既に破壊されています.Bの関数を呼び出すことは意味をなさない。


有効なC++アイテム9:構築や破棄中に仮想関数を呼び出さないでください。派生クラスのデストラクタが実行されたら

は、オブジェクトの派生クラス データメンバは、未定義の値をとるので、C++は、彼らがいない もはや存在しているかのように扱います。基本クラスのデストラクタに入ると、オブジェクト は基本クラスのオブジェクトになり、C++のすべての部分 - 仮想関数、 dynamic_castなどはそのように扱います。

+0

"効果的なC++"について言及してくれてありがとう、私はその時間をもう一度やり直すべきだと思う。 – StahlRat

関連する問題