如何在C++中删除对象

How to delete an object in C++?

本文关键字:删除 对象 C++      更新时间:2023-10-16

构造函数和析构函数调用不匹配,即使在使用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()

您永远不会释放传递给对象的指针,因此它们的析构函数永远不会被调用。

您需要删除析构函数中的指针,以确保存储对象的析构函数也被调用:

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

您还必须修改您的复制构造函数(请参阅规则三)。在这种情况下,这是有问题的,因为您要么必须复制指针值,要么让两个实例都指向同一个对象。在后一种情况下,您必须注意不要删除指针两次。

然而,这正是C++智能指针的用武之地。一个简单得多的方法是:

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

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