條款37 絕不重新定義繼承而來的預設引數值

2021-10-10 17:46:35 字數 1829 閱讀 7855

// 乙個用於描述幾何形狀的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函式決定適當的引數預設值,這比目前實行的"在編譯器決定"的機制更慢而且更加複雜;

但是如果你同時提供預設引數值給basederived 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方法,父類指標指向子類物件,呼叫...