????? 如果你期望衍生類別重新定義一個成員函數,那么你應該在基礎類別中把此函數設為 virtual。
????? 以單一指令喚起不同函數,這種性質稱為Polymorphism,意思是"the ability toassume many forms",也就是多態。
????? 虛擬函數是C++ 語言的Polymorphism 性質以及動態綁定的關鍵。
class CShape // 形狀
02. {
03. private:
04. int m_color;
05. public:
06. void setcolor(int color) { m_color = color; }
07. };
08.
09. classCRect : public CShape // 矩形是一種形狀,它會繼承 m_color 和setcolor()
10. {
11. public:
12. voiddisplay() { ... }
13. };
14.
15. class CEllipse : public CShape // 橢圓形是一種形狀,它會繼承 m_color 和setcolor()
16. {
17. public:
18. voiddisplay() { ... }
19. };
20.
21. class CTriangle : public CShape // 三角形是一種形狀,它會繼承 m_color 和setcolor()
22. { public:
23. void display() { ... }
24. };
25.
26. classCSquare : public CRect // 四方形是一種矩形
27. {
28. public:
29. void display() { ... }
30. };
31.
32. class CCircle : public CEllipse // 圓形是一種橢圓形
33. {
34. public:
35. void display() { ... }
36. };
37. //于是可以這么動作:
38. CSquare square;
39. CRect rect1, rect2;
40. CCircle circle;
41. square.setcolor(1); // 令 square.m_color = 1;
42. m_color m_color
43. CRect::setcolor(int color,
44. square.display(); // 調用CSquare::display
45. rect1.setcolor(2); // 于是rect1.m_color = 2
46. rect1.display(); // 調用CRect::display
47. rect2.setcolor(3); // 于是rect2.m_color = 3
48. rect2.display(); // 調用CRect::display
49. circle.setcolor(4); // 于是circle.m_color = 4
50. circle.display(); // 調用CCircle::display
?????? 兩個矩形對象rect1 和rect2 各有自己的m_color 成員變量,但rect1.setcolor 和rect2.setcolor 卻都通往唯一的CRect::setcolor 成員函數。? 那么CRect::setcolor 如何處理不同對象中的m_color?答案是:成員函數有一個隱藏參數,名為this 指針。當你調用:
rect1.setcolor(2); // rect1 是CRect 對象
rect2.setcolor(3); // rect2 是CRect 對象
??? 編譯器實際上為你做出來的碼是:
CRect::setcolor(2, (CRect*)&rect1);
02.CRect::setcolor(3, (CRect*)&rect2);
??? 不過,由于CRect 本身并沒有聲明setcolor,它是從CShape 繼承來的,所以編譯器實際上產生的碼是:CShape::setcolor(2, (CRect*)&rect1);
02.CShape::setcolor(3, (CRect*)&rect2);
??? 多出來的參數,就是所謂的this 指針。至于類別之中,成員函數的定義:class CShape
02.
03....
04.public:
05.void setcolor(int color) { m_color = color; }
??? 被編譯器整治過后,其實是:class CShape
02.{ ...
03. public:
04. void setcolor(int color, (CShape*)this) { this->m_color = color; }
05.};