什么是虚函数?
简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。
为什么要引入虚函数?
虚函数的作用是实现类的继承所体现的多态性,具体点是实现动态联编。
从程序的角度上来说,在定义了虚函数后,可以在派生类中对虚函数重新定义,以实现统一的接口,不同定义过程,在程序的运行阶段动态地选择合适的成员函数。
什么是多态性?
简单点说,多态性是将接口与实现进行分离;
C++实现运行时多态性的关键途径:在公有派生情况下,一个指向基类的指针可用来访问从基类继承的任何对象。
语法:普通函数的前面加上virtual
[cpp] view plaincopyprint?
1. virtual 函数返回值类型 虚函数名(形参表) 
2. {   
3.     //函数体 
4.
虚函数的调用方式:只能通过指向基类的指针或基类对象的引用来调用虚函数
调用语法:
[cpp] view plaincopyprint?
1. 指向基类的指针变量名->虚函数名(实参表) 
2. 基类对象的引用名. 虚函数名(实参表) 
注意:正常情况下,如果不把函数声明为虚函数,指向基类的指针的访问情况如下:
1)基类指针指向基类对象:基类指针可以直接访问基类对象中的成员
2)基类指针指向派生类对象:基类指针只能访问派生类中的从基类中继承的成员,派生类有同名的函数或成员,也只能调用基类的成员。
如果定义成虚函数时:定义一个基类指针,把不同的派生类对象付给它,会调用对应派生类的函数,而非基类函数。
举例:
[cpp] view plaincopyprint?
1. #include <iostream> 
2. using namespace std; 
3. class A 
4.
5. public
6.     virtual void show() 
7.     { 
8.         cout<<"A"<<endl; 
9.     } 
10. }; 
11. class B:public A 
12.
13. public
14.     void show() 
15.     { 
16.         cout<<"B"<<endl; 
17.     } 
18. }; 
19. class多态性与虚函数 C:public A 
20.
21. public
22.     void show() 
23.     { 
24.         cout<<"C"<<endl; 
25.     } 
26. }; 
27. void main() 
28.
29.     A*a; 
30.     B b; 
31.     C c; 
32.     a=&b; 
33.     a->show(); 
34.     a=&c; 
35.     a->show(); 
36.     system("pause"); 
37.
运行结果:B(换行)C(换行)--指向不同的派生类,调用不同的函数
如果不加基类A中的Virtual,则输出结果:A(换行)A(换行)--基类指针,调用派生类中继承的基类成分
定义虚函数,实现动态联编需要三个条件:
1)必须把动态联编的行为定义为类的虚函数---定义虚函数
2)类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来---类之间是公有继承
3)基类指针指向派生类的对象,然后使用基类指针调用虚函数
注意:
1、使用时,虚函数可以在基类中声明,提供界面。可以在给派生类中定义具体的实现方法,而得到多种方法。
2、多态的实现必须是公有派生。原因:虚函数为了实现多态,虚函数建立在赋值兼容原则上,而赋值兼容原则成立的前提条件是派生类从基类那里公有派生。
3、派生类对基类中虚函数重新定义时,关键字可以写也可以不写,系统可以自动判断
4、虚函数必须是类的成员函数,不能是友元函数,也不能是静态成员函数。因为虚函数需要使用特定的对象激活函数。但是虚函数可以是另一个类的友元函数
5、内敛函数不能是虚函数,因为内敛函数不能在运行时动态确定位置。所以虚函数都是非内敛的
7、一个类的析构函数是虚函数,那么派生而来的所有派生类的析构函数也是虚函数,不管是否使用了关键字virtual