C++杂谈 为什么需要虚析构函数

1.虚函数:在类的成员函数前面加virtual关键字的函数;
一般把虚函数定义在public区,方便在主函数中调用
如果一个类有一个虚函数,则该类就有一个虚函数列表,所有该类的对象都共享这个虚函数表;(QT调试过程中显示的是vptr)
如果一个类有一个或者一个以上的虚函数,则该类有且只有一张虚函数表,每个类都只有一个虚函数表,该类的所有对象都共享这张虚函数表
子类的虚函数表中子类的虚函数覆盖父类的虚函数的情况,当子类将父类的虚函数override时,就覆盖了父类的虚函数;

满足override的条件:函数名相同,函数的返回值相同,形参列表相同;

纯虚函数:形式为virtual void fun1() = 0;
纯虚函数不需要实现,原因是不会被调用到;

抽象基类:至少有一个纯虚函数的类;
抽象基类不能产生该类的对象,但可以有该类的指针或引用;
在子类中必须将父类的纯虚函数实现,不然该子类也是抽象基类;

2.当一个类有子类时,该类的析构函数必须是虚函数,原因:会有资源释放不完全的情况;

class IDelegate
{
public:
	IDelegate(){}
	~IDelegate()	//非虚析构函数
	{
		std::cout << "~IDelegate()!" << std::endl;
	}
};

class CStaticDelegate : public IDelegate
{
public:
	CStaticDelegate() :  {}
	~CStaticDelegate()
	{
		std::cout << "~CStaticDelegate()!" << std::endl;
	}
	
private:
	Func m_Func;
};

template<class T>
class CMethodDelegate : public IDelegate
{
public:
	CMethodDelegate() :  {}
	~CMethodDelegate()
	{
		std::cout << "~CMethodDelegate()!" << std::endl;
	}
};

int main()
{
	IDelegate* demo1 = new CStaticDelegate();
	IDelegate* demo2 = new CMethodDelegate<TestObject>();
	delete demo1;
	delete demo2;
}

Output
在这里插入图片描述

这里可以看到,对象销毁时只调用了父类的析构函数。如果这时子类的析构函数中有关于内存释放的操作,将会造成内存泄露。所以需要给父类的析构函数加上virtual。

class IDelegate
{
public:
	IDelegate(){}
	virtual ~IDelegate()	//虚析构函数
	{
		std::cout << "~IDelegate()!" << std::endl;
	}
};

Output
C++杂谈 为什么需要虚析构函数_第1张图片

你可能感兴趣的:(C++基础,C++散记)