如何在C ++中删除对象?

时间:2016-05-01 19:37:37

标签: c++ object memory-leaks

即使在使用unique_ptr之后,构造函数和析构函数调用也不匹配。有没有办法让构造函数和析构函数调用匹配,否则会有内存泄漏。

#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()

1 个答案:

答案 0 :(得分: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) {} 
};

这样您就不必跟踪指针,也不必覆盖任何复制构造函数等。