2016-05-01 87 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