看如下代碼:
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致敬!