一、基本定義
多載,顧名思義從字面上理解就是重復裝載,打一個不恰當的比方,你可以用一個籃子裝蔬菜,也可以裝水果或者其它,使用的是同一個籃子,但是可以用籃子重復裝載的東西不一樣,
函式多載是C++多型(靜態多型)的特征體現,它可以允許重復使用同一個函式名(籃子)的函式,但是函式的引數串列(籃子裝的東西)是可以不一樣的,這樣就可以利用函式的多載功能設計一系列功能相近,但是功能細節不一樣的函式介面,
二、應用舉例
以同一個函式printData為例:
1 #include <iostream> 2 using namespace std; 3 4 void printData(const char *str, int num) 5 { 6 //函式體; 7 } 8 9 void printData(const char *str) 10 { 11 //函式體; 12 } 13 14 void printData(double data, int num) 15 { 16 //函式體; 17 } 18 19 void printData(int data, int num) 20 { 21 //函式體; 22 } 23 24 void printData(long data, char num) 25 { 26 //函式體; 27 } 28 29 class Test 30 { 31 public: 32 void MyPrint(int num) {cout << "class int: " << num << endl;} 33 void MyPrint(float num) {cout << "class float: " << num << endl;} 34 void MyPrint(char num) {cout << "class char: " << num << endl;} 35 }; 36 37 int main(void) 38 { 39 printData("hello", 5); // (const char *str, int num) 40 printData("hello"); // (const char *str) 41 printData(1993.0, 97); 42 printData(1993, 98); 43 printData(1993L, 99); 44 Test test1; 45 test1.MyPrint(2); // class int: 2 46 test1.MyPrint(2.0f); // class float: 2.0 浮點型必須要顯式型別,否則編譯器不知道該轉換為int還是float, 47 test1.MyPrint("hello"); // class char: hello 48 return 0; 49 }
使用多載函式時,需要在函式呼叫中使用與對應的多載函式匹配的函式引數型別,
而如下:
1 unsigned int para = 4321; 2 printData(4321, 5);
此時的printData呼叫和哪個原型匹配呢?答案它不與任何函式原型匹配,而沒有匹配的原型不會停止呼叫其中某一個函式,C++會嘗試用標準的強制型別轉換與之匹配,比如使用 printData(double data, int num),就可以將para的型別強制轉換為double型別,但是還有printData(int data, int num)和printData(long data, char num)這兩個函式可以強制轉換para,因此,C++將拒絕這種函式的呼叫,將這種呼叫視為錯誤,
多載函式通常用在同一個作用域內,用同一個函式名命名一組功能相似的函式,這樣做減少了函式名的數量,提高了函式的通用性,避免了名字空間的污染,對于程式的可讀性有很大的好處,
三、非函式多載的情況
下面這種兩種情況不能視為函式多載:
1 int fun(int a); 2 int fun(int &a);
從編譯器的角度出發,引數a與引數串列原型int a和int &a都匹配,編譯器無法確定使用哪個函式,為避免這種混亂,編譯器在檢查引數型別時將把型別本身和型別參考看作是同一個特征型別,
1 int fun(int a, float b); 2 double fun(int a, float b);
C++不允許這樣的方式多載函式,雖然回傳值可以不一樣,但是引數串列必須不一樣,
四、函式多載的使用原則
(1)、僅當函式的基本功能比較相近,但是需要使用不同形式的引數實作功能時才應該使用函式多載,盡量不要用同一函式名去實作完全不相干的功能;
(2)、在同一個作用范圍內使用函式多載,同一個范圍即:同一個命名空間或者同一個類等;
(3)、多載函式的名稱必須相同,函式的引數串列須不相同,即引數串列中引數的型別,引數的個數或引數的順序不相同;
(4)、多載函式可以有相同的回傳值型別或者不同的回傳值型別,反之僅僅是回傳型別不同不足以作為函式的多載,
五、FAQ
1、C++中對函式多載是如何處理的?
在.cpp檔案中,雖然兩個函式的函式名一樣,但是,C++編譯器在內部使用“名稱修飾”或“名稱矯正”轉換,它根據函式中引數串列的區別為每個函式進行加密 ,例如:
int fun(int a, float b)和double fun(int a, float b)
編譯器在內部可以轉換為:
?fun@@YAHHH@Z和?fun@@YAMMM@Z
"?"表示名稱開始,"?"后邊是函式名;“@@YA”表示引數表開始,后邊的3個字符分別表示回傳值型別,兩個引數型別;“@Z”表示名稱結束,
由于在.cpp檔案中,兩個函式生成的符號表中字符的名稱不一樣,所以是可以編譯通過的,
2、C語言中為什么不能支持函式多載?
編譯器在編譯.c檔案時,只會給函式進行簡單的重命名,具體的方法是給函式名之前加上"_”;所以編譯前兩個函式名相同的函式在編譯之后的函式名也照樣相同;因此呼叫時會因為不知道到底呼叫哪個而出錯,
int fun(int a, float b)和double fun(int a, float b)
編譯器在內部都轉換為:_fun,無法區分,
只有不同的函式名字int fun1(int a, float b)和double fun2(int a, float b)
編譯器在內部轉換為:_fun1和_fun2,這才能區分開來,
更多技術內容和書籍資料獲取敬請關注微信公眾號“明解嵌入式”
本文來自博客園,作者:Sharemaker,轉載請注明原文鏈接:https://www.cnblogs.com/Sharemaker/p/17033659.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/541428.html
標籤:其他
下一篇:GC耗時高,原因竟是服務流量小?
