淺析C++中的函數重載
一、什么是函數重載?
函數重載簡介:在C++中,可以為兩個或兩個以上的函數提供相同的函數名稱,只要參數類型不同,或者參數類型相同而參數個數不同,又或者參數類型參數個數相同,參數次序不同,稱為函數重載。
舉例:
int my_max(int a,int b)
{
return a>b?a:b;
}
char my_max(char a, char b)
{
return a>b?a:b;
}
double my_max(double a,double b)
{
return a>b?a:b;
}
int main()
{
cout<<my_max(12,23)<<endl;
cout<<my_max(12.23,23.34)<<endl;
cout<<my_max('a','b')<<endl;
return 0;
}二、函數重載的規(guī)則
1.編譯器的工作
當一個函數名在同一個域中被聲明多次,兩個函數的參數表中參數個數或者類型順序不同,則認為是函數重載。
注意:調用者與函數之間的關系在編譯時就被綁定在一起,其地址關聯(lián)。
2.函數重載的原理
編譯器如何知道與哪個函數關聯(lián)?為什么C語言不能進行函數重載,而C++可以?
編譯器是如何知道調用者與哪個函數關聯(lián)的呢?——通過名字粉碎(名字修飾)技術 。
“C”和“C++”函數是在編譯鏈接時通過修飾名來識別,而修飾名就是編譯器在編譯函數定義或聲明時生成的字符串,修飾名由函數名、類名、調用約定、返回類型、參數等共同決定的。
那調用約定有哪些呢?
_stdcall 回調 :是Pascal缺省的調用方式,通常用于Win32 Api中,函數采用從右到左的壓棧方式,自己在退出時清空堆棧。
C調用約定(_cdecl):按從右到左的順序壓參數入棧,由調用者把參數彈出,對于傳送參數的內存棧是由調用者來維護的,因此實現可變參數的函數只能使用該調用約定。
_fastcall快速調用:通過寄存器傳遞參數(實際上,它是用ECX和EDX傳送前兩個雙字或更小的參數,剩下參數仍然自右至左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧),它的主要特點就是速度快
thiscall:僅僅應用于C++類中的成員函數,this指針存放于ECX寄存器,參數自右向左壓
C語言為什么不能實現函數重載?
C語言編譯函數名修飾約定規(guī)則:C語言修飾函數名非常簡單,_cdecl是C/C++的缺省調用方式,調用約定前面添加下劃線前綴即可,例:_functionname

例:

C語言編譯時無法通過修飾名區(qū)分調用者與函數之間的關系
而在C++中函數名修飾約定規(guī)則是:
(1)以“?”標識函數名開始,后跟函數名
(2)函數名后面以“@@YA”標識參數表的開始,后跟參數表
(3)參數表以代號表示
(4)參數表的第一項為該函數的返回值類型,其后依次為參數的數據類型,指針標識在其所指數據類型前
(5)參數表后以@Z標識整個名字的結束,如果該函數無參數,則以“Z”標識結束。
常用代號如下:
X -- void
D -- char
E -- unsigned char
F -- short
H -- int
I -- unsigned int
J -- long
K -- unsigned long
M -- float
N -- double
_N -- bool
PA -- 表示指針,后面的代號表明指針類型
例:

編譯鏈接時,把參數類型,函數返回類型作為命名的一部分,編譯器編譯時可以區(qū)分調用哪個函數。
3.判斷函數重載的依據
可以確認為函數重載:
(1)函數名相同,參數類型不同
(2)參數類型相同,參數個數不同
(3)參數類型相同,參數個數相同,參數次序不同
不能作為判斷函數重載的依據的:
(1)參數表相同,返回類型不同
例:

當調用函數時,有時候不需要返回值,編譯器不知道調去用哪個函數,所以返回類型不能作為判斷重載的依據。
到此這篇關于淺析C++中的函數重載的文章就介紹到這了,更多相關C++函數重載內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

