[C++]虚析构函数

虚析构函数

虚函数(virtual)用在类中的普通方法中的时候,会根据虚表(vtable)查找派生类中对于当前函数名的用法,虚函数可以用于实现多态,而实现多态的时候(父类引用或者指针接收子类对象),在删除该父类指针时不会调用子类的析构函数,而如果子类对象中具有开辟在堆区上的内存空间,就不能通过子类析构函数删除该部分空间,造成内存泄漏,此时就用到了虚析构函数,与普通虚函数不同,它并非直接查找子类中的函数覆盖自身,而是同时调用自身析构函数与子类构造函数,这样就解决了利用多态时可能造成内存泄漏的问题。

注意:构造函数不可以被设定为虚函数:虚函数对应一个虚表vtable,这个vtable存储在对象的内存空间中,虚函数被通过查询虚表vtable调用,所以一定要通过构造函数实例化内存空间,才会有虚表,所以构造函数不可能为虚函数。

#include<iostream>
class Base
{
public:
	Base() { std::cout << "Base Constructor\n"; }
	~Base() { std::cout << "Base Destructor\n"; }
};

class Derived : public Base
{
public:
	Derived() { std::cout << "Derived Constructor\n"; }
	~Derived() { std::cout << "Derived Destructor\n"; }
};

int main()
{
	Base* base = new Base();
	delete base;
	std::cout << "-----------------\n";
	Derived* derived = new Derived();
	delete derived;
	std::cout << "-----------------\n";
	Base* poly = new Derived();
	delete poly;
	std::cin.get();
}

运行发现父类构造函数和子类构造函数都能被正确调用,当删除poly时只有父类的析构函数被调用了,而子类的析构函数没有被调用,导致内存泄漏。![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/879c21f9fb494b7e9598278d40932d13.png在这里插入图片描述
原因:当删除poly时,它没有被标记为虚函数,是一个父类的指针,由于没有虚函数表(vtable),它只会调用自身析构函数。


现在对父类Base的虚函数加上virtual关键字变为虚函数,再在子类中加入一个开辟在堆区的数组

#include<iostream>
class Base
{
public:
	Base() { std::cout << "Base Constructor\n"; }
	virtual ~Base() { std::cout << "Base Destructor\n"; }
};

class Derived : public Base
{
public:
   int* a;
	Derived() 
	{ 
	a = new int[5];
	std::cout << "Derived Constructor\n"; 
	}
	~Derived()
	{
	 delete[] a;
	 std::cout << "Derived Destructor\n";
	 }
};

int main()
{
	Base* base = new Base();
	delete base;
	std::cout << "-----------------\n";
	Derived* derived = new Derived();
	delete derived;
	std::cout << "-----------------\n";
	Base* poly = new Derived();
	delete poly;
	std::cin.get();
}

在这里插入图片描述
析构函数被标记为virtual,意味着c++知道需要调用子类中的析构函数。在调用析构函数时再同时调用类析构函数。它会先调用派生类析构函数,然后在层次结构中向上调用基类析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值