2016-05-01 10 views
3

unique_ptrを使用した後でも、コンストラクタとデストラクタの呼び出しが一致しません。それ以外の場合は、メモリリークが発生すると一致するコンストラクタとデストラクタの呼び出しを行う方法はありますか?C++でオブジェクトを削除するには?

#include <iostream> 
using namespace std; 
class P 
{ 
    public: 
    P() { cout<<"P()\n"; } 
    virtual ~P() { cout<<"~P()\n"; } 
}; 
class D: public P 
{ 
    P *q; 
    public: 
    D(P *p):q(p) { cout<<"D()\n"; } 
    ~D() { cout<<"~D()\n"; } 
}; 
class A: public D 
{ 
    public: 
    A(P *p):D(p) { cout<<"A()\n"; } 
    ~A() { cout<<"~A()\n"; } 
}; 
class B: public D 
{ 
    public: 
    B(P *p):D(p) { cout<<"B()\n"; } 
    ~B() { cout<<"~B()\n"; } 
}; 
int main() 
{ 
    P *p = new B(new A(new P())); 
    delete p; 
    return 0; 

}

OUTPUT: 
P() 
P() 
D() 
A() 
P() 
D() 
B() 
~B() 
~D() 
~P() 
+2

'D'はデストラクタで' qを削除する 'べきです。コピー構築を禁じます。 – LogicStuff

+0

"unique_ptrを使った後でも" - あなたのコードはunique_ptrを使用しません –

答えて

5

あなたがオブジェクトに渡されたポインタを解放されることはありませんので、そのデストラクタが呼び出されることはありません。

あなたは、格納されたオブジェクトのデストラクタがあまりにも呼ばれていることを確認するために、あなたのデストラクタでポインタを削除する必要があります。

class D: public P 
{ 
    P *q; 
public: 
    D(P *p) : q(p) { cout << "D()" << endl; } 
    ~D() { delete q; cout << "~D()" << endl; } 
}; 

あなたはまた、(Rule of Threeを参照)、その後、あなたのコピーコンストラクタを変更する必要があります。 この場合、ポインタ値をコピーするか、両方のインスタンスが同じオブジェクトを指すようにする必要があるため、この場合は問題があります。後者の場合、ポインタを2回削除しないように注意する必要があります。

ただし、これはC++スマートポインタが作成された場所です。はるかに簡単な方法は、次のようになります。

class D : public P 
{ 
    unique_ptr<P> q; 
public: 
    D(P *p) : q(p) {} 
}; 

あなたは、ポインタを追跡する必要はありません。この方法で、あなたはまた、任意のコピーコンストラクタと、このようなをオーバーライドする必要はありません。

+0

そして3つのルールについて忘れないでください – teivaz

+0

ヒントありがとうございます - 回答を更新しました – tobspr

+0

それは素晴らしいです。みんなありがとう 。 – user3798283

関連する問題