C++缺省參數問題
一般函數
-
有函數聲明時,默認參數可以放在函數聲明或者定義中,但只能放在二者之一,建議放在聲明中
-
沒有函數(原型)時,默認參數在函數定義時指定
static void Test0(int a = 0); ... void Test0(int a) { cout << a << endl; } ... void Test1(int a, int b = 2, char c = '3', string d = "4") { cout << a << endl << b << endl << c << endl << d << endl; }
-
一旦某個參數開始指定默認值,它右邊的所有參數都必須指定默認值:函數聲明時,必須按照從右向左的順序,依次給與默認值
-
在調用具有默認參數的函數時,若某個有默認參數的參數使用了默認參數, 它右邊的所有參數都使用默認參數:函數調用時,必須按照從左向右的順序,依次賦值
#include<bits/stdc++.h> using namespace std; static void Test0(int a = 0); static void Test1(int a, int b = 2, char c = '3', string d = "4"); int main() { Test0(); Test1(1); //'2'會轉換成int,執行Test1 Test1(1, '2'); return 0; } void Test0(int a) { cout << a << endl; } void Test1(int a, int b, char c, string d) { cout << a << endl << b << endl << c << endl << d << endl; }
類的一般成員函數
- 同上
類的虛函數
結論:決不要重新定義繼承而來的缺省參數值
#include<bits/stdc++.h>
using namespace std;
class A {
public:
virtual void Test0(int a = 5) = 0;
};
class B : public A {
public:
virtual void Test0(int a = 6) override {
cout << a << endl;
}
};
int main() {
A* a = new B();
a->Test0();
return 0;
}
原因:
-
虛函數是動態綁定的,即具體被調用的虛函數由那個對象的動態類型決定
-
缺省參數是靜態綁定的,即編譯階段就確定了虛函數的默認參數一定來自Base類;
這樣做的原因是:運行效率。如果缺省參數被動態綁定,需要類似查虛表的機制,這將比現在采用的在編譯階段確定缺省值的機制更慢更復雜
比如:上方代碼如果調用Test0()
-
參數壓棧
-
返回地址壓棧
-
調用函數:因為虛函數,需要虛表找到函數指針,跳到函數實際地址執行函數
注意到此時參數已經壓棧,雖然可以用類似的機制實現動態綁定,但沒必要
-