C++基类的虚析构函数(virtual)与内存泄露

一、C++ 内存泄露

C++本身没有GC机制,所以需要开发人员做好内存管理。一般情况,C++内存泄露主要原因为:

1. 在构造和析构函数中,没有匹配new和delete;
2. 没有将基类的析构函数定义为virtual(如果没有定义virtual的话,析构函数只清理自己的成员)



二、虚析构函数的作用

下面根据三个场景来说明基类中virtual虚析构函数的作用

1. 派生类指针指向派生类对象
#include <iostream>
using namespace std;

class Father{
public:
    Father(){
        cout << "Father()" << endl;
    }
	virtual ~Father(){
        cout << "~Father()" << endl;
    }

};
class Son : public Father{
public:
    Son(){
        cout << "Son()" << endl;
    }
    ~Son(){
        cout << "~Son()" << endl;
    }

};

int main(int argc, char** argv){
    Son *obj = new Son;
    delete obj;
}

当派生类指针指向派生类的时候,运行结果如下:
在这里插入图片描述
释放指针obj的时候,调用顺序:基类构造函数 -> 派生类构造函数 -> 派生类析构函数 -> 基类析构函数

2.基类指针指向派生类(基类用virtual,虚析构函数)
#include <iostream>
using namespace std;

class Father{
public:
    Father(){
        cout << "Father()" << endl;
    }
	virtual ~Father(){
        cout << "~Father()" << endl;
    }

};
class Son : public Father{
public:
    Son(){
        cout << "Son()" << endl;
    }
    ~Son(){
        cout << "~Son()" << endl;
    }

};

int main(int argc, char** argv){
    Father *obj = new Son;
    delete obj;
}

用virtual析构函数的基类指向派生类,运行结果如下(与派生类指向派生类相同):
在这里插入图片描述
释放指针obj的时候,调用顺序:基类构造函数 -> 派生类构造函数 -> 派生类析构函数 -> 基类析构函数

3.基类指针指向派生类(无virtual)
#include <iostream>
using namespace std;

class Father{
public:
    Father(){
        cout << "Father()" << endl;
    }
	~Father(){
        cout << "~Father()" << endl;
    }

};
class Son : public Father{
public:
    Son(){
        cout << "Son()" << endl;
    }
    ~Son(){
        cout << "~Son()" << endl;
    }

};

int main(int argc, char** argv){
    Father *obj = new Son;
    delete obj;
}

基类的析构函数没有virtual,用基类指针指向派生类的时候,运行结果如下:
在这里插入图片描述
释放指针obj的时候,调用顺序:基类构造函数 -> 派生类构造函数 -> 基类析构函数
这种情况只释放了基类的资源,没有调用派生类的析构函数,对obj进行delete的时候,派生类的资源没有被删除,造成内存泄露。



三、基类virtual析构函数的作用

将一个基类指针指向派生类对象,如果基类的析构函数没有定义成virtual虚函数,编译器的静态绑定,在删除基类指针的时候,只会调用基类的析构函数,也就意味着只释放了基类的资源,派生类的成员没有被释放,因此导致内存没有被完全释放,即内存泄漏。
为了防止此类内存泄露,需要将基类的析构函数定义为virtual,从而可以在删除基类指针的时候,一并释放派生类的成员。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值