日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

c++函数重载机制实现原理

發(fā)布時(shí)間:2025/6/15 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++函数重载机制实现原理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文鏈接:https://blog.csdn.net/gogogo_sky/article/details/72807123

一、c++函數(shù)重載的定義:

同一作用域類,一組函數(shù)的函數(shù)名相同參數(shù)列表不同(參數(shù)個(gè)數(shù)不同/參數(shù)類型不同)返回值可同可不同

二、函數(shù)重載的作用:

重載函數(shù)通常用來(lái)在同一個(gè)作用域內(nèi)?用同一個(gè)函數(shù)名 命名一組功能相似的函數(shù),這樣做減少了函數(shù)名的數(shù)量,避免了名字空間的污染,對(duì)于程序的可讀性有很大的好處。

三、函數(shù)重載是一種靜態(tài)多態(tài):

(1)多態(tài):用同一個(gè)東西表示不同的形態(tài);?
(2)多態(tài)分為:?
靜態(tài)多態(tài)(編譯時(shí)的多態(tài))?
動(dòng)態(tài)多態(tài)(運(yùn)行時(shí)的多態(tài));?
(3)函數(shù)重載是一種靜態(tài)多態(tài);

四、c++函數(shù)重載的原理:

(一)?
編譯器在編譯.cpp文件中當(dāng)前使用的作用域里的同名函數(shù)時(shí),根據(jù)函數(shù)形參的類型和順序會(huì)對(duì)函數(shù)進(jìn)行重命名(不同的編譯器在編譯時(shí)對(duì)函數(shù)的重命名標(biāo)準(zhǔn)不一樣)但是總的來(lái)說(shuō),他們都把文件中的同一個(gè)函數(shù)名進(jìn)行了重命名;

  • 在vs編譯器中:?
    根據(jù)返回值類型(不起決定性作用)+形參類型和順序(起決定性作用)的規(guī)則重命名并記錄在map文件中。
  • 在linux g++ 編譯器中:?
    根據(jù)函數(shù)名字的字符數(shù)+形參類型和順序的規(guī)則重命名記錄在符號(hào)表中;從而產(chǎn)生不同的函數(shù)名,當(dāng)外面的函數(shù)被調(diào)用時(shí),便是根據(jù)這個(gè)記錄的結(jié)果去尋找符合要求的函數(shù)名,進(jìn)行調(diào)用;

五、為什么c語(yǔ)言不能實(shí)現(xiàn)函數(shù)重載

編譯器在編譯.c文件時(shí),只會(huì)給函數(shù)進(jìn)行簡(jiǎn)單的重命名;具體的方法是給函數(shù)名之前加上”_”;所以加入兩個(gè)函數(shù)名相同的函數(shù)在編譯之后的函數(shù)名也照樣相同;調(diào)用者會(huì)因?yàn)椴恢赖降渍{(diào)用那個(gè)而出錯(cuò);

六、實(shí)驗(yàn)說(shuō)明:

(一)在C語(yǔ)言中,如果兩個(gè)函數(shù)的函數(shù)名相同,不管形參和返回值是否相同,程序運(yùn)行都會(huì)發(fā)生錯(cuò)誤?
在.c文件中;寫出下列代碼,在vs2008運(yùn)行出錯(cuò):

#include<stdio.h>int Add(int a,int b) {return a+b; }float Add(float a,float b) {return a+b; } int main() {Add(10,20);Add(20.0f,30.0f);return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

運(yùn)行結(jié)果:報(bào)錯(cuò)—函數(shù)“int Add(int,int)”已有主體?
錯(cuò)誤原因:?
程序從編譯到運(yùn)行出結(jié)果幾個(gè)階段。其中一個(gè)階段提到生成符號(hào)表。?
我們來(lái)看一下上邊的函數(shù)成的符號(hào)表。符號(hào)表是在.map文件里,在vs里默認(rèn)不顯示符號(hào)表文件。要想顯示出來(lái),這樣設(shè)置:?
工程名右擊—>屬性—->配置屬性—->鏈接器—–>調(diào)試—->生成映射文件—>選擇是;?
上邊寫有兩個(gè)同名函數(shù)的c程序中根本編譯不通過(guò)(報(bào)錯(cuò):Add函數(shù)已有主體)就無(wú)法生成符號(hào)表。所以,我去掉一個(gè)函數(shù),讓程序編譯通過(guò),看看函數(shù)名在符號(hào)表中的命名?

通過(guò)這個(gè)我們可以得出,c程序中的Add()函數(shù)在符號(hào)表中的重命名就是函數(shù)名前邊加個(gè)下劃線。所以如果一個(gè)c程序中出現(xiàn)了同名函數(shù),他們?cè)诜?hào)表中的命名一樣,這樣調(diào)用時(shí)就出現(xiàn)了沖突。

(二)將上面的代碼在改為.cpp文件,編譯之后在map中查看兩個(gè)Add()函數(shù)的名字;?

這里我們可以看出,在.cpp文件中,雖然兩個(gè)函數(shù)的函數(shù)名一樣,但是他們?cè)诜?hào)表中生成的名稱不一樣。?
‘?’表示名稱開(kāi)始,‘?’后邊是函數(shù)名“@@YA”表示參數(shù)表開(kāi)始,后邊的3個(gè)字符分別表示返回值類型,兩個(gè)參數(shù)類型。“@Z”表示名稱結(jié)束。?
由于在.cpp文件中,兩個(gè)函數(shù)生成的符號(hào)表中的名稱不一樣,所以是可以編譯通過(guò)的。

那么既然c++編譯器和c編譯器對(duì)函數(shù)名的重命名規(guī)則不一樣;?
那么怎么在一個(gè).cpp文件中調(diào)用.c文件的函數(shù)??
以前寫的一篇相關(guān)文章?
(三)不同的編譯器對(duì)c++代碼的函數(shù)重命名規(guī)則不一樣;?
下面看看在linux下g++編譯器對(duì)相同代碼函數(shù)名的重命名;

cpp文件在linux虛擬機(jī)里需要用g++編譯。?
安裝g++很簡(jiǎn)單。命令: yum install gcc gcc-c++?
安裝好了之后就可以了。運(yùn)行程序之后,使用命令:objdump a.out -t > test.out?
-t是表示生成符號(hào)表,最后是將生成的符號(hào)表用重定向符號(hào)放在test.out文件。打開(kāi)test.out文件,就會(huì)發(fā)現(xiàn),整形數(shù)相加的函數(shù)Add(int a,int b)生成的符號(hào)表中,Add函數(shù)名被記錄為_Z3Addiii,其中。_Z表示符號(hào)表名稱開(kāi)始,?3代表函數(shù)名的字符個(gè)數(shù)iii代表按順序三個(gè)形參的類型;?
可以看出:同樣的.cpp文件在window的vs2008編譯器和linux的g++編譯中,相同的函數(shù)名進(jìn)過(guò)編譯之后的重新命名不一樣;



《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的c++函数重载机制实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。