虚函数(virtual)

虚函数(virtual)

上面提到动态多态主要通过虚函数机制实现,这里介绍以下虚函数。和普通的函数声明方式相同,只要在函数的返回值前加上virtual关键字,该函数就为虚函数,即virtual 函数类型 函数名(形式参数)

虚函数的作用:允许通过基类的指针或引用来访问基类和派生类的同名函数。

1、虚成员函数

#include <iostream>
using namespace std;
class Teacher
{
public:
	virtual void work()
	{
		cout << "上课" << endl;
	}
};
 
class MathTeacher :public Teacher
{
public:
	virtual void work()
	{
		cout << "数学课" << endl;
	}
};
 
class ChinsesTeachar :public Teacher
{
public:
	virtual void work()
	{
		cout << "语文课" << endl;
	}
};
 
class EnglishTeachar :public Teacher
{
public:
	virtual void work()
	{
		cout << "英语课" << endl;
	}
};
 
int main()
{
	cout << "上课啦!!!" << endl;
	MathTeacher tea;
	tea.Teacher::work();
	tea.MathTeacher::work();//没有虚函数只能这样调用基类的函数
	//定义一个指针数组
	Teacher** teacher = new Teacher*[3]();
	MathTeacher math;
	EnglishTeachar english;
	teacher[0] = new MathTeacher();
	teacher[1] = new ChinsesTeachar();
	teacher[2] = new EnglishTeachar();
	
	for (int i = 0; i < 3; ++i)
	{
		teacher[i]->work();
	}
	return 0;
}

可以通过基类的指针区访问派生的方法。

2、虚析构函数

在c++中不能声明虚构造函数,但可以声明虚析构函数。虚析构函数的作用就是为了:防止因基类指针指向派生类的对象而造成的内存泄漏问题。

上面提到,通过基类指针可以指向派生类的对象,从而使用派生类方法。如果基类的析构函数不是虚函数的话,编译器在执行时,就不会动态绑定,从而就是导致编译器指调用了基类的析构函数,而没有调用派生类的析构函数,这样就会有潜在的内存泄漏的风险。而通过虚析构函数可以解决这一问题。

构造函数为什么不能是虚函数?

因为虚函数的执行依赖于虚函数表,而虚函数表的初始化是在构造函数中完成,所以构造函数无法声明为虚函数。

为什么默认的析构函数不是虚函数?

虚函数的工作是基于虚函数表的,而虚函数表时需要消耗空间的。而在程序中又不一定又继承,所以默认的析构函数不是虚函数。

总结:一个类的构造函数无法被声明为虚函数,而析构函数则可以声明为虚函数。如果程序中存在继承那么最好将析构函数设置为虚析构函数。

3、纯虚函数

//声明格式:virtual 函数类型 函数名( 参数列表 ) =0; 可以没有函数体的实现
virtual int fun(int n,int m)=0;

拥有纯虚函数的类,为抽象类。抽象类不能实例化对象。抽象类的子类会自动继承该纯虚函数,如果子类中任然没有实现该方法,那么该子类任然为纯虚函数。


版权声明:本文为qq_37200329原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。