// 乙個用於描述幾何形狀的class
class
shape
;// 所有形狀都必須提供乙個函式,繪出自己
virtual
void
draw
(shapecolor color = red)
const=0
;};class
rectangle
:public shape
;class
circle
:public shape
;
現在考慮這些指標:
shape *ps;
//靜態型別為shape*
shape *pc =
new circle;
//靜態型別為shape*
shape *pr =
new rectangle;
//靜態型別為shape*
ps,pc,pr,都被宣告為pointer-to-shape型別,所以他們都以它為靜態型別,
物件的所謂動態型別,則是指"目前所指物件的型別".也就是說,動態型別可以表現出乙個物件將會發生什麼行為;pc
的動態型別為circle*
,pr
的動態型別為rectangle *
,ps
沒有動態型別
virtual函式是動態繫結,而預設引數值卻是靜態繫結
,意思是你可能會在"呼叫乙個定義於derived class
內的virtual
函式的同時,卻使用base class
為它所制定預設引數值":
pr-
>
draw()
;// 呼叫rectangle::draw(shape::red)
為什麼c++以這種方式來運作呢? 答案在於執行效率,如果預設引數值是動態繫結,編譯器就必須有某種辦法在執行期為virtual函式決定適當的引數預設值,這比目前實行的"在編譯器決定"的機制更慢而且更加複雜;
但是如果你同時提供預設引數值給base
和derived class
使用者,又會發生什麼事情的?
clas shape
;virtual
void
draw
(shapecolor color = red)
const=0
;};class
rectangle
:public shape
;
上述**重複又帶著相依性;如果shape內的預設引數值改變了,derived classes也必須改變;解決辦法是令base class
內的乙個public non-virtual
函式呼叫private virtual
函式,後者可被derived classes
重新定義
clas shape
;void
draw
(shapecolor color = red)
const
private
:virtual
void
dodraw
(shapecolor color)
const=0
;// 真正的工作在此處完成};
class
rectangle
:public shape
;
條款37 絕不重新定義繼承而來的預設引數值
條款37 絕不重新定義繼承而來的預設引數值 靜態繫結就是在程式中被宣告時所採用的型別 includeusing namespace std class shape virtual void draw shapecolor color red const 0 class rectangle publi...
條款37 絕不要重新定義繼承而來的預設引數值
總結 不要重新定義乙個繼承而來的預設引數值,因為 預設引數值是靜態繫結 而virtual函式 你唯一應該覆寫的東西 是動態繫結。我們應該知道,virtual函式是動態繫結 dynamically bound 預設引數值卻是靜態繫結 statically bound 物件的靜態型別 static ty...
37 絕不重新定義繼承而來的預設引數值
1 由於絕不重新定義繼承而來的non virtual方法,現只考慮帶有預設引數值的virtual方法。2 為什麼絕不重新定義繼承而來的預設引數值?預設引數值是靜態繫結,virtual方法是動態繫結。現在考慮父類virtual方法帶有預設引數值,子類重寫了virtual方法,父類指標指向子類物件,呼叫...