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

use*_*283 3 c++ memory-leaks object

即使在使用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;
Run Code Online (Sandbox Code Playgroud)

}

OUTPUT:
P()
P()
D()
A()
P()
D()
B()
~B()
~D()
~P()
Run Code Online (Sandbox Code Playgroud)

tob*_*spr 5

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

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

class D: public P
{
    P *q;
public:
    D(P *p) : q(p) { cout << "D()" << endl; }
    ~D() { delete q; cout << "~D()" << endl; }
};
Run Code Online (Sandbox Code Playgroud)

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

但是,这就是C++智能指针的用武之地.一种更简单的方法是:

class D : public P
{
    unique_ptr<P> q;
public:
    D(P *p) : q(p) {} 
};
Run Code Online (Sandbox Code Playgroud)

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