語句 | 解釋章節 |
---|---|
int A::b(int c) { } | 類 |
a->b | 資料結構 |
class A: public B {}; | 友元和繼承 |
|
|
20 10 |
main
聲明瞭兩個指向 Polygon
的指標(名為 ppoly1
和 ppoly2
)。它們被分別賦予了 rect
和 trgl
的地址,這兩個物件分別是 Rectangle
和 Triangle
型別的。這樣的賦值是有效的,因為 Rectangle
和 Triangle
都是從 Polygon
派生出來的類。ppoly1
和 ppoly2
(使用 ppoly1->
和 ppoly2->
)是有效的,並允許我們訪問它們所指向物件的成員。例如,在前面的例子中,以下兩個語句是等價的:
|
|
ppoly1
和 ppoly2
的型別都是指向 Polygon
的指標(而不是指向 Rectangle
或指向 Triangle
的指標),所以只能訪問從 Polygon
繼承的成員,而不能訪問派生類 Rectangle
和 Triangle
的成員。這就是為什麼上面的程式直接使用 rect
和 trgl
來訪問兩個物件的 area
成員,而不是透過指標;指向基類的指標無法訪問 area
成員。area
是 Polygon
的成員而不是其派生類的成員,那麼就可以透過指向 Polygon
的指標來訪問 area
成員。但問題是,Rectangle
和 Triangle
實現了不同版本的 area
,因此沒有一個通用的版本可以在基類中實現。virtual
關鍵字。
|
|
20 10 0 |
Polygon
、Rectangle
和 Triangle
)都有相同的成員:width
、height
,以及函式 set_values
和 area
。area
在基類中被宣告為 virtual
,因為它之後在每個派生類中被重新定義。非虛成員也可以在派生類中被重新定義,但派生類的非虛成員不能透過基類的引用來訪問。也就是說,如果在上面的例子中從 area
的宣告中移除 virtual
,那麼所有三次對 area
的呼叫都將返回零,因為在所有情況下,被呼叫的都將是基類的版本。virtual
關鍵字本質上所做的,是允許派生類中與基類中同名的成員能夠透過指標被正確呼叫,更確切地說,是當指標型別為指向基類的指標,而它正指向派生類的物件時,就像上面的例子一樣。Polygon
的一個成員是虛擬函式,但它仍然是一個常規類,甚至可以例項化一個物件(poly
),它有自己對成員 area
的定義,該定義總是返回 0。Polygon
類非常相似。它們是隻能用作基類的類,因此允許擁有沒有定義的虛成員函式(稱為純虛擬函式)。其語法是用 =0
(一個等號和一個零)來替換其定義。Polygon
可能看起來像這樣:
|
|
area
沒有定義;它被 =0
所取代,這使其成為一個純虛擬函式。包含至少一個純虛擬函式的類被稱為抽象基類。Polygon
不能用於宣告像下面這樣的物件:
|
|
|
|
|
|
20 10 |
Polygon*
)來引用,並且每次都會呼叫正確的成員函式,僅僅因為它們是虛擬函式。這在某些情況下非常有用。例如,抽象基類 Polygon
的一個成員甚至可以使用特殊指標 this
來訪問正確的虛成員,即使 Polygon
本身沒有實現這個函式。
|
|
20 10 |
|
|
20 10 |
ppoly
指標:
|
|
Polygon
的指標”型別,但分配的物件則直接宣告為派生類的型別(Rectangle
和 Triangle
)。![]() 友元和繼承 | ![]() 目錄 | ![]() 型別轉換 |