C++ 虛函數的默認參數問題


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()

    • 參數壓棧

    • 返回地址壓棧

    • 調用函數:因為虛函數,需要虛表找到函數指針,跳到函數實際地址執行函數

      注意到此時參數已經壓棧,雖然可以用類似的機制實現動態綁定,但沒必要


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM