學習過C++類的繼承與多態的時候,但是很多的童鞋回過頭來都忘記之中關於虛函數和純虛函數的細節,甚至將他們混淆。
--------------------------------------------------------------------------------
§虛函數
虛函數是動態多態性的基礎,其調用的方式是動態聯編(又稱晚期聯編,簡單解釋為只有在程序運行時才決定調用基類的還是子類的,系統會根據基類指針所指向的對象來決定要調用的函數);
非虛函數與其相反,是靜態聯編(調用已經在編譯時期就決定了;在編譯時期,系統已經根據指針所屬的類型確定了要調用的函數)。
?class shape
{
public:
shape(){};
void draw()
{
畫圖形;
}
};
class rectangle : public shape
{
public:
rectangle(){};
void draw()
{
畫方形;
}
};
class round : public shape
{
public:
round(){};
void draw()
{
畫圓形;
}
};
void main()
{
shape * s;
s = new rectangle();
s->draw();
s = new round();
s->draw();
}
我主程序中的意思是要畫方形和畫圓形,可執行的結果都是畫圖形(叫你兩兒子出來,怎麼出來的都是你啊,扯淡麼),這很明顯不符合我們的要求和多態的要求。所以虛函數必須應運而生。
?class shape
{
public:
shape(){};
virtual void draw() //注意這裡設置為虛函數
{
畫圖形;
}
};
class rectangle : public shape
{
public:
rectangle(){};
void draw()
{
畫方形;
}
};
class round : public shape
{
public:
round(){};
void draw()
{
畫圓形;
}
};
void main()
{
shape * s;
s = new rectangle();
s->draw();
s = new round();
s->draw();
}
這就滿足我們了,一個是畫方形,一個是畫圓形。
發現:即使不在基類shape當中把draw設置為虛函數,我們只要直接在主函數當中直接聲明子類的對象,調用draw,這種情況下是符合多態的思想的,
?void main()
{
round r;
? r.draw();
}
這就有疑問了,為什麼還需要virtual關鍵字(虛函數)的存在呢?
上面的例子只是一個兩個派生類,如果shape有成百上千個派生類,難道我們調用派生類的draw的時候都聲明一個派生類的對象嗎?很明顯不可能,所以虛函數的情況下,我們只要聲明一個shape的指針就好了。
傳送門:
C++虛函數和純虛函數(2):http://www.BkJia.com/kf/201112/113649.html
搗亂小子2011-12-08