天天看點

C++學習之函數重載、啞元參數、預設參數、内聯函數

  1. 函數重載

    1)定義

    在相同作用域,定義的同名函數,但是它們的參數必須有所區分,這樣的函數将構成重載關系

    注:函數能否重載和傳回類型無關.

    #include <iostream>
    
    using namespace std;
    
    void func(int i){
    	cout << "func(int)" << endl;
    }
    void func(int a, int b){
    	cout << "func(int ,int)" << endl;
    }
    void func(int a, float b){
    	cout << "func(int ,float)" << endl;
    }
    
    int main(void){
    	func(10);
    	func(10, 20);
    	func(10, 1.23f);//1.23後邊必須加f
    	void (*pfunc)(int, float) = func;//定義一個傳回值為空,參數為int,float的函數指針,将func
    									//指派給它,實際上将第三個函數傳遞給func
    	pfunc(10,20);//并不會調用第一個,而是調用第三個
    	return 0;
    }
               

    2)函數重載比對

    調用重載關系的函數時,編譯器會根據實參與形參的比對程度,自動選擇最優比對版本,目前g++編譯器比對一般規則:

    完全比對>=常量轉換>更新轉換>降級轉換>省略号比對

    #include <iostream>
    
    using namespace std;
    
    //char -> int:更新轉換
    void bar(int i){
    	cout << "bar(1)" << endl;
    }
    
    //char -> const char:常量轉換
    void bar(const char c){
    	cout << "bar(2)" << endl;
    }
    
    //short -> char:降級轉換
    void fun(char c){
    	cout << "fun(1)" << endl;
    }
    
    //short -> int:更新轉換
    void fun(int i){
    	cout << "fun(2)" << endl;
    }
    
    //省略号比對,可以比對任意多個,任意類型個實參
    void hum(int i, ...){
    	cout << "hum(1)" << endl;
    }
    
    //double -> int: 降級轉換
    void hum(int i, int j){
    	cout << "hum(2)" << endl;
    }
    
    int main(void){
    	char c = 'a';
    	bar(c);
    	short s = 10;
    	fun(s);
    	hum(10, 1.23);
    	return 0;
    }
               

    3)函數重載原理

    C++編譯器是通過對函數進行換名,将參數表的類型整合到新的函數名中,解決函數重載和名字沖突的沖突.

    筆試題:C++中extern "C"聲明的作用?

    可以在函數聲明前面加入extern “C”,要求C++編譯器不對該函數進行換名,便于C程式直接調用該函數.

    注:被extern "C"聲明的函數無法重載

  2. 啞元參數

    1)定義

    定義函數時,隻有類型而沒有變量名形參成為啞元.

    void func(int/啞元/){

    }

    2)使用啞元場景

    –》在操作符重載,區分前後++、–

    –》為了相容以前的舊代碼

    算法庫:void math_func(int a,int b){…}

    使用者:

    int main(void){

    math_func(10,20);

    math_func(30,40);

    }

    更新算法庫:void math_func(int a,int/啞元/){…}

    使用者:

    int main(void){

    math_func(10,20);

    math_func(30,40);

    }

  3. 預設參數(預設實參)

    1)定義

    可以為函數的部分參數或全部參數指定預設值,調用該函數時,如果不給實參,就取預設值作為預設實參。

    void func(int a,int b,int flag=0/預設參數/){}

    2)靠右原則,如果函數的一個參數有預設值,那麼該參數右側的所有參數都必須帶有預設值.

    3)如果函數的定義和聲明分開,預設參數應該是寫在函數的聲明部分,而定義部分不寫。

    #include <iostream>
    using namespace std;
    //函數聲明
    void func(int a,int b = 20,int c = 30);
    //void func(int i){}//歧義錯誤
    int main(void){
        func(11,22,33);//11 22 33
        func(11,22);//11 22 30
        func(11);//11 20 30
        return 0;
    }
    //函數定義
    void func(int a,int b/*=20*/,int c/*=30*/){
        cout << "a=" << a << ",b=" << b << ",c=" 
            << c << endl;
    }
               
  4. 内聯函數(inline)

    1)定義

    使用inline關鍵字修飾的函數即為内聯函數,編譯器将會嘗試進行内聯優化,可以避免函數調用的開銷,提高代碼執行效率.

    inline void func(void){}//内聯函數

    2)使用說明

    –》多次調用的,小而簡單的函數适合内聯

    –》調用次數極少或大而複雜的函數不适合内聯

    –》遞歸函數不能内聯優化

    –》虛函數不能内聯優化

    注:内聯函數隻是一種建議而不是強制要求,能否進行内聯優化是由編譯器決定的,有些函數不加inline修飾也會預設處理為内聯優化,而有些函數即便加了inline修飾也會被編譯器忽略掉.

繼續閱讀