寫這篇是因為發現了類繼承中乙個有趣的現象。我們都知道,c++類中的virtual函式是動態繫結的,那麼virtual函式的預設引數呢?
想必大家對動態繫結和靜態繫結都不陌生了吧?簡單來說,動態繫結就是執行期決定執行的函式(或行為),靜態繫結則是編譯期確定的,或者宣告時確定的。
virtual函式是動態繫結的,而預設引數卻是靜態繫結。為了說明這個問題,先看乙個再簡單不過的例子:
#include using namespace std;
class base
};class derived_1 : public base
};class derived_2 : public base
};int main()
定義乙個基類base,宣告乙個virtual函式print_num,預設引數值為5;定義兩個base的派生類,分別定義virtual函式print_num,預設引數為整數10和浮點數3.14159。根據經驗,我們都知道,在執行成員函式時,會根據指標所指物件型別執行相應型別下的函式,p1指向的動態型別為derived_1,p2指向的動態型別為derived_2,因此,p1->print_num()應執行的是derived_1類中的print_num(),p2->print_num()應該執行的是derived_2中的print_num()。實際是否這樣呢?讓我們來看一下執行結果:
有點意外是不是?
p3和p4的輸出結果在意料之內。那麼怎樣解釋p1和p2的輸出結果?
p1的靜態型別為base,動態型別為derived_1,那麼在執行期執行p1->print_num()時,會自動呼叫derived_1的同名函式print_num(),但由於預設引數為靜態繫結,因此,傳入的預設引數為整數5,因此p1->print_num()的輸出是合理的。
p2的靜態型別為base,動態型別為derived_2,執行期間貌似應該執行derived_2得print_num(),但由於輸入引數為靜態繫結,即為int型的數值5,而derived_2中沒有對print_num(int)的定義,因此實際執行的還是基類的print_num()函式。
那麼問題來了,如果讓p2列印乙個float型別的數值,結果會是怎樣?結果很可能仍然出乎我們的意料,我們在上面的程式裡再新增幾行:
int main()
p2->print_num(f)並沒有如我們預期列印出float數值,而是仍然呼叫了base中的print_num(),並對傳進去的float引數做取整輸出。這大概是最反直覺的結果了吧!
python 預設引數值 預設引數值
該樓層疑似違規已被系統摺疊 隱藏此樓檢視此樓 最常用的一種形式是為乙個或多個引數指定預設值。這會建立乙個可以使用比定義時允許的引數更少的引數呼叫的函式,例如 def ask ok prompt,retries 4,complaint yes or no,please while true ok in...
Python 預設引數值
預設引數值 python 預設引數值,對於一些函式來說,你可能為希望使一些引數可選並使用預設的值,以避免使用者不想為他們提供值的情況。預設引數值可以有效幫助解決這一情況。你可以通過在函式定義時附加乙個賦值運算子 來為引數指定預設引數值。要注意到,python預設引數值應該是常數。更確切地說,預設引數...
Python函式預設引數值
python的函式機制提供了可選引數的功能,可選引數需要放在引數列表的後幾個引數。當呼叫這些函式時,如果不想設定這些引數,就可以不用設定而直接使用函式定義的時候設定的引數預設值。同樣的,呼叫函式的時候也可以重新設定引數,這將覆蓋預設設定的引數。def func x,y 2 print x y fun...