什么是派生类的基类子对象?_C++内存泄漏(基类指针指向派生类对象)

当使用基类指针指向派生类对象时,没有问题,但是要是想把这个基类指针给删掉,这时候问题就来了,例如下面这个例子:

class BaseClass {
private:
    char *name;
public:
    BaseClass(int size) {
        name = new char[size];
        for (int i = 0; i 'a';
    }
 // 基类的析构函数
    ~BaseClass() { delete name; }
};

class DeriveClass : public BaseClass {
private:
    char *count;
public:
    DeriveClass(int size) : BaseClass(size) {
        count = new char[size];
        for (int i = 0; i 'b';
    }
    // 派生类的析构函数
    ~DeriveClass() { delete count; }
};
int main() {
    // 多态用法,基类指针指向派生类对象,没毛病
    BaseClass *obj = new DeriveClass(16);
    // 删除基类指针,出现了问题!
    delete obj;
    return 0;
}

上面的程序乍一看看不出个毛病来,现在对 BaseClass *obj = new DeriveClass(16); 设置断点,进行单步调试,可以观察到构造函数过程是:

new DeriveClass(16)
    |
BaseClass(16)
    |
DeriveClass(16)
    |
    end

这个顺序完全正确,先构造基类再构造派生类嘛,执行完后,内存状态是这样的:

01da6e5d3c9ce8809d3b49f92a7e30eb.png内存状态表示

可以得知操作系统给这两个对象中的成员分配内存到了 name : 0x1061980count : 0x10619c0

那么执行 delete obj; 时,顺序是这样的:

delete obj
    |
~BaseClass()
    |
    end

从上面可以看出来,竟然只执行了基类的析构函数,而没有执行派生类的析构函数,那么这时的内存表示是怎么样的?见下图:

7ae65e45473d49e1ac2473fb7e97c0c3.png内存状态表示

由此可见,在不经意间,就造成了内存泄漏问题,那么该如何解决这个问题呢?

很简单,只需要把基类的析构函数声明为 virtual 就可以了,这样强制去执行子类的析构函数。

不过,这样还是有两种结果,例如下面是一种结果:

class BaseClass {
    // 其他都一样
    virtual ~BaseClass() { delete name; }
};
class DeriveClass : public BaseClass {
    // 其他都一样
    ~DeriveClass() override { delete count; }
};

这个时候,是先执行的派生类析构函数,再执行基类析构函数。

另一种结果是:

class BaseClass {
    virtual ~BaseClass() { delete name; }
};
class DeriveClass : public BaseClass {
    // 删掉了自己的析构函数
};

这个情况下,才是先执行基类析构函数,再执行派生类析构函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值