对于如下代码:
//Base.cpp
#include<iostream>
using namespace std;
class Base
{
public :
Base(char xx) { x = xx; }
virtual void who()
{
cout << "Base class: " << x << "\n" ;
}
protected:
char x;
} ;
class First_d : public Base
{
public :
First_d(char xx, char yy):Base(xx)
{
y = yy;
}
void who()
{
cout << "First derived class: "<< x << ", " << y << "\n" ; }
protected:
char y;
} ;
class Second_d : public First_d
{
public :
Second_d( char xx, char yy, char zz ) : First_d( xx, yy )
{
z = zz;
}
void who()
{
cout << "Second derived class: "<< x << ", " << y << ", " << z << "\n" ;
}
protected:
char z;
} ;
void main()
{
Base B_obj( 'A' ) ;
First_d F_obj( 'T', 'O' ) ;
Second_d S_obj( 'E', 'N', 'D' ) ;
Base * p ;
p = & B_obj ; p -> who() ;
p = &F_obj ; p -> who() ;
p = &S_obj ; p -> who() ;
F_obj.who() ;
( ( Second_d * ) p ) -> who() ;
while(1);
}
我们注意到Base类中的void who()
函数添加了关键字virtual
上述代码块运行结果如下:
Base class: A
First derived class: T, O
Second derived class: E, N, D
First derived class: T, O
Second derived class: E, N, D
假如去掉who()前的关键字virtual
,运行结果会变为:
Base class: A
Base class: T
Base class: E
First derived class: T, O
Second derived class: E, N, D
发生这样的情况的关键是:virtual
关键字使得 随着p指向不同对象,this指针作类型转换执行不同实现版本
温馨提示:
- 一个虚函数,在派生类层界面相同的重载函数都保持虚特性
- 虚函数必须是类的成员函数
- 不能将友员说明为虚函数,但虚函数可以是另一个类的友员
- 析构函数可以是虚函数,但构造函数不能是虚函数
- 在派生类中重载基类的虚函数要求函数名、返回类型、参数个数、
参数类型和顺序完全相同 - 如果仅仅返回类型不同,C++认为是错误重载
- 如果函数原型不同,仅函数名相同,丢失虚特性