C++ 函式過載 詳解
阿新 • • 發佈:2018-12-30
在實際開發中,有時候我們需要實現幾個功能類似的函式,只是有些細節不同。例如希望交換兩個變數的值,這兩個變數有多種型別,可以是 int、float、char、bool 等,我們需要通過引數把變數的地址傳入函式內部。在C語言中,程式設計師往往需要分別設計出三個不同名的函式,其函式原型與下面類似:
引數列表又叫引數簽名,包括引數的型別、引數的個數和引數的順序,只要有一個不同就叫做引數列表不同。
【示例】藉助函式過載交換不同型別的變數的值:
200, 100
56.93, 12.5
B, A
1, 0
本例之所以使用
既然標準庫已經提供了 swap() 函式,本例為何又要自己實現一遍呢,這不是費力不討好嗎?交換兩個變數的值是一個經典且實用的函式過載案例,本例這樣做僅僅是為了教學演示,並不是要替代標準庫中的 swap(),讀者在以後的編碼過程中也應該堅持使用標準庫中的 swap()。
通過本例可以發現,過載就是在一個作用範圍內(同一個類、同一個名稱空間等)有多個名稱相同但引數不同的函式。過載的結果是讓一個函式名擁有了多種用途,使得命名更加方便(在中大型專案中,給變數、函式、類起名字是一件讓人苦惱的問題),呼叫更加靈活。
在使用過載函式時,同名函式的功能應當相同或相近,不要用同一函式名去實現完全不相干的功能,雖然程式也能執行,但可讀性不好,使人覺得莫名其妙。
注意,引數列表不同包括引數的個數不同、型別不同或順序不同,僅僅引數名稱不同是不可以的。函式返回值也不能作為過載的依據。
函式的過載的規則:
- void swap1(int *a, int *b); //交換 int 變數的值
- void swap2(float *a, float *b); //交換 float 變數的值
- void swap3(char *a, char *b); //交換 char 變數的值
- void swap4(bool *
引數列表又叫引數簽名,包括引數的型別、引數的個數和引數的順序,只要有一個不同就叫做引數列表不同。
【示例】藉助函式過載交換不同型別的變數的值:
- #include <iostream>
- using namespace std;
- //交換 int 變數的值
- void Swap(int *a, int *b){
- int temp = *
- *a = *b;
- *b = temp;
- }
- //交換 float 變數的值
- void Swap(float *a, float *b){
- float temp = *a;
- *a = *b;
- *b = temp;
- }
- //交換 char 變數的值
- void Swap(char *a, char *b){
- char temp = *a;
- *a = *b;
- *b = temp;
- }
- //交換 bool 變數的值
- void Swap(bool *a, bool *b){
- char temp = *a;
- *a = *b;
- *b = temp;
- }
- int main()
- //交換 int 變數的值
- int n1 = 100, n2 = 200;
- Swap(&n1, &n2);
- cout<<n1<<", "<<n2<<endl;
- //交換 float 變數的值
- float f1 = 12.5, f2 = 56.93;
- Swap(&f1, &f2);
- cout<<f1<<", "<<f2<<endl;
- //交換 char 變數的值
- char c1 = 'A', c2 = 'B';
- Swap(&c1, &c2);
- cout<<c1<<", "<<c2<<endl;
- //交換 bool 變數的值
- bool b1 = false, b2 = true;
- Swap(&b1, &b2);
- cout<<b1<<", "<<b2<<endl;
- return 0;
- }
200, 100
56.93, 12.5
B, A
1, 0
本例之所以使用
Swap
這個函式名,而不是使用swap
,是因為
C++ 標準庫已經提供了交換兩個變數的值的函式,它的名字就是swap
,位於algorithm
標頭檔案中,為了避免和標準庫中的swap
衝突,本例特地將S
大寫。既然標準庫已經提供了 swap() 函式,本例為何又要自己實現一遍呢,這不是費力不討好嗎?交換兩個變數的值是一個經典且實用的函式過載案例,本例這樣做僅僅是為了教學演示,並不是要替代標準庫中的 swap(),讀者在以後的編碼過程中也應該堅持使用標準庫中的 swap()。
通過本例可以發現,過載就是在一個作用範圍內(同一個類、同一個名稱空間等)有多個名稱相同但引數不同的函式。過載的結果是讓一個函式名擁有了多種用途,使得命名更加方便(在中大型專案中,給變數、函式、類起名字是一件讓人苦惱的問題),呼叫更加靈活。
在使用過載函式時,同名函式的功能應當相同或相近,不要用同一函式名去實現完全不相干的功能,雖然程式也能執行,但可讀性不好,使人覺得莫名其妙。
注意,引數列表不同包括引數的個數不同、型別不同或順序不同,僅僅引數名稱不同是不可以的。函式返回值也不能作為過載的依據。
函式的過載的規則:
- 函式名稱必須相同。
- 引數列表必須不同(個數不同、型別不同、引數排列順序不同等)。
- 函式的返回型別可以相同也可以不相同。
- 僅僅返回型別不同不足以成為函式的過載。
C++ 是如何做到函式過載的
C++程式碼在編譯時會根據引數列表對函式進行重新命名,例如void
Swap(int a, int b)
會被重新命名為_Swap_int_int
,void
Swap(float x, float y)
會被重新命名為_Swap_float_float
。當發生函式呼叫時,編譯器會根據傳入的實參去逐個匹配,以選擇對應的函式,如果匹配失敗,編譯器就會報錯,這叫做過載決議(Overload
Resolution)。不同的編譯器有不同的重新命名方式,這裡僅僅舉例說明,實際情況可能並非如此。從這個角度講,函式過載僅僅是語法層面的,本質上它們還是不同的函式,佔用不同的記憶體,入口地址也不一樣