C++ 为什么基类的析构函数要声明为虚函数

1、为什么声明基类析构函数为虚函数?
(1)基类指针 指向 基类对象:不用考虑基类析构函数是否声明为虚函数。
(2)基类指针 指向 派生类对象:若基类析构函数不为虚函数,在delete基类指针时,只会调用基类的析构函数,不会调用派生类的析构函数(资源未释放,基类无法操作派生类中非继承的成员),进而可能导致内存泄漏。

2、如下代码示例

#include<iostream>
using namespace std;

//基类A
class classA
{
public:
	classA(){ cout << "Construct in classA" << endl; };

	~classA(){ cout << "Destruct in classA" << endl; };

	void print(){ cout << "Print classA" << endl; };
};
//派生类B
class classB : public classA
{
public:
	classB(){ cout << "Construct in classB" << endl; };

	~classB(){ cout << "Destruct in classB" << endl; };

	void print(){ cout << "Print classB" << endl; };
};

//基类C
class classC
{
public:
	classC(){ cout << "Construct in classC" << endl; };

	//虚析构函数
	virtual ~classC(){ cout << "Destruct in classC" << endl; };

	//虚成员函数
	virtual void print(){ cout << "Print classC" << endl; };
};
//派生类D
class classD : public classC
{
public:
	classD(){ cout << "Construct in classD" << endl; };

	//以下两个函数可不加virtual关键字修饰,由于函数重写编译时会默认加上(基类C中为虚函数)
	//析构函数比较特殊,编译时名字一样,因此也构成函数重写
	virtual ~classD(){ cout << "Destruct in classD" << endl; };

	virtual void print(){ cout << "Print classD" << endl; };
};

int main()
{
	cout << "------------part 1------------" << endl;
	classB *ptrB = new classB;//派生类指针指向派生类对象
	ptrB->print();
	delete ptrB;
	
	cout << endl << "------------part 2------------" << endl;
	classA *ptrA = new classB;//基类指针指向派生类对象(基类非虚析构)
	ptrA->print();
	delete ptrA;

	cout << endl << "------------part 3------------" << endl;
	classC *ptrC = new classD;//基类指针指向派生类对象(基类虚析构)
	ptrC->print();
	delete ptrC;

	cout << endl << "------------part 4------------" << endl;
	classC *ptrC1 = new classC;//基类指针指向基类对象
	ptrC1 ->print();
	delete ptrC1 ;

	getchar();
	return 0;
}

3、执行结果及分析
(1)执行结果
在这里插入图片描述
(2)分析
①part 1:派生类对象创建与销毁时,构造及析构函数的调用顺序为,基类构造→派生类构造→派生类析构→基类析构。

②part 2:基类A析构函数不为虚函数,delete基类指针时,未调用派生类B析构函数(非多态,根据指针类型调用)。

③part 3:与part 2对比(上图中红色标记),基类C中析构函数为虚函数,此时形成多态(与类型无关,只与对象有关),delete基类指针时,先调用派生类的析构函数,后调用基类的析构函数。

④part 4:与part 3对比(Print函数输出),基类指针指向基类对象时,调用基类的成员函数;指向派生类对象时,调用派生类的成员函数。这便是多态(动态绑定),在程序执行过程中,动态决定调用哪个函数。

4、多态介绍
多态(动态绑定)的核心是虚函数、虚表、虚表指针,此处推荐一篇头条上的文章《C++ 虚函数表剖析》,链接:C++ 虚函数表剖析

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值