2016-05-01 91 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)。 在這種情況下,這是有問題的,因爲您要麼必須複製指針值,要麼讓兩個實例指向同一個對象。在後一種情況下,你必須小心不要刪除指針兩次。

但是,這是C++智能指針的作用。一個更簡單的方法是:

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

這樣你就不必跟蹤指針,你也不必重寫任何拷貝構造函數和這樣。

+0

並且不要忘記三條規則 – teivaz

+0

感謝您的提示 - 更新了答案 – tobspr

+0

這很棒。謝謝大家 。 – user3798283