C++相對于C語言而言支持函數(shù)重載是其極大的一個特點,相信在使用C語言的時候大家如果要寫一個實現(xiàn)兩個整型數(shù)據(jù)相加的函數(shù)還要寫一個浮點型數(shù)據(jù)相加的函數(shù),那么這兩個函數(shù)的名字絕對不可以一樣,這樣無疑在我們使用這個函數(shù)的時候增加了復雜性,但是在C++中我們卻可以很好的解決這個問題,因為在C++中函數(shù)是支持重載的也就是說兩個函數(shù)的函數(shù)名可以一樣,這樣并不會出現(xiàn)函數(shù)名重定義的問題,但是我們在使用的時候也要遵守一些規(guī)定,這些規(guī)定我們會在接下來的討論中提到,下面我們就來分析在C++中函數(shù)是如何實現(xiàn)函數(shù)的重載的。

在這里我們用C語言和C++分別寫兩個函數(shù),通過函數(shù)的符號表來觀察函數(shù)名在經(jīng)過編譯之后究竟是什么形式的

下面就是我們的測試代碼:

photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 1 #include<iostream> 2  3 using namespace std; 4  5  6  7 int Add(int x, int y) 8  9 {10 11 int z = 0;12 13 z = x + y;14 15 return z;16 17 }18 19 20 21 double Add(double x, double y)22 23 {24 25 double z = 0;26 27 z = x + y;28 29 return z;30 31 }32 33  34 35 int main()36 37 {38 39 cout<<Add(1,3)<<endl;40 41 cout<<Add(1.5,3.5)<<endl;42 43 return 0;44 45 }

photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 

VS2008的編譯環(huán)境下:

我們生成.map文件,然后可以查看函數(shù)在經(jīng)過編譯之后的函數(shù)名稱為下圖所示:

 

 photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 

不難發(fā)現(xiàn)上圖中函數(shù)命名的一些規(guī)律(當然這個規(guī)律只是片面的針對于VS2008編譯環(huán)境):

1.以“?”開始和以”@Z”結尾

2.函數(shù)的名稱緊接“?”之后

3.在函數(shù)明德后面分別是函數(shù)返回值類型修飾符、參數(shù)列表中的參數(shù)的類型修飾符

 

下面我們把這個相同的函數(shù)改為c語言的代碼

代碼如下:

 

photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 1 //#include<iostream> 2  3 //using namespace std; 4  5 #include<stdio.h> 6  7   8  9  10 11 int Add(int x, int y)12 13 {14 15 int z = 0;16 17 z = x + y;18 19 return z;20 21 }22 23  24 25 double Add(double x, double y)26 27 {28 29 double z = 0;30 31 z = x + y;32 33 return z;34 35 }36 37  38 39 int main()40 41 {42 43 //cout<<Add(1,3)<<endl;44 45 //cout<<Add(1.5,3.5)<<endl;46 47 return 0;48 49 }

photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 

這時我們編譯的話就會出現(xiàn)錯誤:

 

 photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 

這里告訴我們函數(shù)名出現(xiàn)重定義

那么這是為什么呢?

這時我們注釋掉一個函數(shù)然后編譯后查看.map文件,查看函數(shù)重命名之后的名稱

 

 photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 

 

這里我們可以發(fā)現(xiàn)函數(shù)在編譯之后重命名的名稱僅僅只是在函數(shù)名稱的前面加上了一個"_"(下劃線),這樣我們就不難分析了,C和C++編譯的時候對函數(shù)的重命名機制是完全不一樣的

1.C語言中僅僅只是在函數(shù)的名稱的前面加上了"_"(下劃線)

2.C++有自己的命名修飾規(guī)則,他會根據(jù)函數(shù)的參數(shù)列表中變量的類型等進行相應的類型修飾

 雖然C++支持函數(shù)的重載但是我們在使用的時候也要注意以下幾點:

1.函數(shù)的重載只是出現(xiàn)在同一作用域,例如假如兩個工程里的函數(shù)名稱相同,但是他們也不是函數(shù)的重載

2.函數(shù)名相同,函數(shù)的參數(shù)列表不同,返回值可同可不同,為什么函數(shù)返回值可同可不同呢?

這是因為在不同的編譯環(huán)境下對于函數(shù)名稱的修飾并不是相同的,下面就是在Linux環(huán)境下函數(shù)編譯后重命名的形式:

 

photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設計培訓,網(wǎng)站建設培訓

 

仔細觀察不難發(fā)現(xiàn)在Linux環(huán)境下的函數(shù)重命名的一些規(guī)則:

1.以“_Z”z作為開頭,緊隨其后的數(shù)字是函數(shù)名稱的單詞的個數(shù)

2.函數(shù)的名稱后面有函數(shù)的參數(shù)列表中參數(shù)的類型修飾符,i是int型,d是double型

通過以上的闡述相信大家可以對C++中為什么可以實現(xiàn)函數(shù)重載有了清晰的認識,那么我們也就不難回答為什么在C++中調用被C編譯過后的函數(shù)應該在前面加上 extern "C" 聲明了。

       這是因為我們當前是處于c++語言環(huán)境,這個時候我們?nèi)绻恢付ㄒ{用的那個函數(shù)是用C語言編譯的函數(shù),那么當前在C++文件中編譯時就會報錯說是該函數(shù)是一個無法解析的外部符號,因為在編譯運行的時候我們當前的程序會從符號表中去找相應的函數(shù)名,可是C++和C編譯后生成的符號表中函數(shù)的名是不同的,那么這個函數(shù)也就是一個無法解析的外部符號了,但是當你用extern “C” 指明該函數(shù)是用C語言編譯的函數(shù),那么當前代碼在編譯運行的時候就會從用C語言編譯的那個符號表文件中去查找相應的函數(shù)名,這樣整個程序的編譯運行費也就沒有問題了。

http://www.cnblogs.com/kj1501120706/p/7107172.html