虚函数是重载的另一种表现形式。这是一种动态的重载方式,它提供了一种更为灵活的、运行时的多态性机制。虚函数允许函数调用与函数体之间的联系在运行时才建立,也就是在运行时才决定如何动作,即所谓的动态连编。

   虚函数首先是基类中的成员函数,但这个成员函数前面加了关键字virtual,并在派生类中被重载。

    它的一般形式:

   virtual  返回类型   函数名(形参表)

{

    函数体

}

   在基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义。虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型的顺序,都必须与基类中的原型完全相同。

  对于虚函数的定义有几点说明:

1、由于虚函数使用的基础是赋值兼容规则,而赋值兼容规则成立的前提条件是派生类从基类公有派生。

2、必须首先在基类中定义虚函数。由于“基类”与“派生类”是相对的,因此这项说明并不表明必须在类等级的最高层类中声明虚函数。在实际应用中,应该在类等级内需要具有动态多态性的几个层次中的最高层类内首先声明虚函数。

3、在派生类中对基类中声明的虚函数进行重新定义时,关键字virtual可以写可以不写。但在容易引起混乱的情况下,最好在派生类的虚函数进行重新定义时加上关键字virtual。

4、虽然使用对象名和点运算符的方式可以调用虚函数,若 

  定义 基类 Base对象 b 虚函数为show() 

  b.show();可以调用虚函数Base::show();但是这种调用在编译时进行的是静态连编,没有充分利用虚函数的特性,只有通过基类指针访问虚函数是才能获得运行时的多态性

5、一个虚函数无论被继承多少次,它仍然保持虚函数的特性。

6、虚函数必须是其所在类的成员函数,不能是友元函数,也不能是静态成员函数,因为虚函数调用要靠特定的对象来决定该激活那个函数。

7、内联函数不能为虚函数,因为内联函数是不能在运行中动态确定其位置的。即使虚函数在类的内部定义,编译时仍将其看作是非内联的。

8、构造函数不能是虚函数,但是析构函数可以是虚函数,而且通常说明为虚函数。