看如下代码:
CSales aSales("崔贤");
CSales* pSales;
CWage* pWager;
pSales=&aSales;
pWager=&aSales;//用基类指针指向派生类对象
pWager->setSales(800.0);//出错,因为CWage没有定义setSales
pSales->setSales(800.0);//正确,因为CSales定义了setSales
pWager->comutePay();//调用CWage的comutePay()
pSales->comutePay();//调用CSales的comutePay()
我们得出结论:指向派生类对象的基类指针只能调用基类中定义的函数。我们不能否认的是,pWager指向的是其派生类CSales对象;但是pWager却不能能调用CSales的成员函数;所以我们只能这样理解:对于指向派生类对象的基类指针,派生类的成员函数被屏蔽掉了。
下面提出一个需求:遍历链表中的每一个元素显示职员的名字并且计算工资。代码如下:
int count=0;
CEmployee* pEmp;
.......
while(pEmp=anInter.getNext())
{
count++;
cout<<count<<' '<<pEmp->getName()<<endl;//正确
cout<<"工资"<<‘ '<<pEmp->comutePay()<<endl;//出错
}
打印职员名字没有错误,虽然pEmp是基类指针,当指向派生类时,调用的getName()从基类继承下来的,在此,我要强调pEmp是指向派生类的,所以getName()返回的必然是派生类对象的名字。但是打印工资时出错,因为每个派生类都有自己的comutePay(),pEmp只能调用基类的comutePay(),而基类没有这个函数,必然会出错。虚函数在此应运而生!
在基类中声明一个纯虚函数:virtual float comutePay()=0; 问题迎刃而解!
至于虚函数的性质,想必任何一本C++书上都会讲的很清楚,我在此就不啰嗦了。我以此篇文章来说明我对于两个东西的理解:虚基类和指向派生类对象的基类指针。在此借鉴了侯捷《深入浅出MFC》上的示例,没办法,侯捷举的例子太恰当了,以至于我忍不住要拿来用一下,向侯Sir致敬!