版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第C++超詳細(xì)分析函數(shù)重載的使用目錄一、函數(shù)重載分析(上)1.1重載的定義1.2函數(shù)重載的定義1.3函數(shù)重載需要滿足的條件1.4編譯器調(diào)用重載函數(shù)的準(zhǔn)則1.5函數(shù)重載的注意事項1.6小結(jié)二、函數(shù)重載分析(下)2.1函數(shù)重載遇上函數(shù)指針2.2C++和C的相互調(diào)用2.3使得C代碼只會以C的方式被編譯的解決方案2.4小結(jié)
一、函數(shù)重載分析(上)
1.1重載的定義
定義:同一個標(biāo)識符在不同的上下文有不同的意義
1.2函數(shù)重載的定義
用同一個函數(shù)名定義不同的函數(shù)當(dāng)函數(shù)名和不同的參數(shù)搭配時函數(shù)的含義不同
如下:
下面看一段代碼,感受一下:
#includestdio.h
#includestring.h
intfunc(intx)
returnx;
intfunc(inta,intb)
returna+b;
intfunc(constchar*s)
returnstrlen(s);
intmain(intargc,char*argv[])
printf("%d\n",func(3));
printf("%d\n",func(4,5));
printf("%d\n",func("D.T.Software"));
return0;
}
下面為輸出結(jié)果:
1.3函數(shù)重載需要滿足的條件
函數(shù)重載至少滿足下面的一個條件:
參數(shù)個數(shù)不同參數(shù)類型不同參數(shù)順序不同
下圖所示就是參數(shù)的順序不同:
下面看一個函數(shù)默認(rèn)參數(shù)遇上函數(shù)重載的實例程序:
#includestdio.h
intfunc(inta,intb,intc=0)
returna*b*c;
intfunc(inta,intb)
returna+b;
intmain(intargc,char*argv[])
intc=func(1,2);
return0;
}
下面為輸出結(jié)果:
編譯報錯,因為模棱兩可。如果說調(diào)用第一個函數(shù)說的過去,因為符合函數(shù)默認(rèn)參數(shù)規(guī)則,c的值已經(jīng)確定;調(diào)用第二個函數(shù)也符合常理,所以編譯不會通過。
1.4編譯器調(diào)用重載函數(shù)的準(zhǔn)則
將所有同名函數(shù)作為候選者
嘗試尋找可行的候選函數(shù)
精確匹配實參通過默認(rèn)參數(shù)能夠匹配實參通過默認(rèn)類型轉(zhuǎn)換匹配實參
匹配失敗
最終尋找到的候選函數(shù)不唯一,則出現(xiàn)二義性,編譯失敗。無法匹配所有候選者,函數(shù)未定義,編譯失敗。
1.5函數(shù)重載的注意事項
重載函數(shù)在本質(zhì)上是相互獨立的不同函數(shù)重載函數(shù)的函數(shù)類型不同函數(shù)返回值不能作為函數(shù)重載的依據(jù)
函數(shù)重載是由函數(shù)名和參數(shù)列表決定的!?。?/p>
函數(shù)重載的本質(zhì)是什么?下面通過一段代碼深入分析,編譯環(huán)境為VS2012。
#include"stdafx.h"
#includestdio.h
intadd(inta,intb)//int(int,int)
returna+b;
intadd(inta,intb,intc)//int(int,int,int)
returna+b+c;
intmain()
printf("%p\n",(int(*)(int,int))add);
printf("%p\n",(int(*)(int,int,int))add);
return0;
}
由C語言的知識可以知道,函數(shù)名就是函數(shù)的入口地址,所以輸出結(jié)果如下:
可以看到,兩個add()函數(shù)的入口地址不一樣,所以這兩個add是兩個不同的函數(shù)。
編譯器是如何看待這兩個add()函數(shù)的呢?下面來深入分析。先看一下編譯器產(chǎn)生的中間結(jié)果,在Test-Debug-Test.obj文件中。
然后使用VS2012里面自帶的命令行工具查看Test.obj里面有什么東西。
上圖示為VS2012命令行所在位置
輸入dumpbin,如下:
這里只需要關(guān)系SYMBOLS(符號表),符號表就是編譯器在編譯過程中根據(jù)源代碼所生成的一張表,這張表有程序的函數(shù)名變量等等。
輸入以下命令,其中/symbols后面為Test.obj所在的位置。
找到下面的地方,可以看到編譯器編譯(int__cdecladd(int,int))時標(biāo)識符為add@@YAHHH@Z;而編譯器編譯(int__cdecladd(int,int,int))時標(biāo)識符為add@@YAHHHH@Z,也就是說編譯器在編譯這兩個函數(shù)時已經(jīng)把這兩個函數(shù)分別對待,盡管它們名字一樣,所以兩個add()函數(shù)的入口地址不一樣,這就很好理解了。
1.6小結(jié)
函數(shù)重載是C++中引入的概念函數(shù)重載用于模擬自然語言中的詞匯搭配函數(shù)重載使得C++具有更豐富的語義表達(dá)能力函數(shù)重載的本質(zhì)為相互獨立的不同函數(shù)C++中通過函數(shù)名和函數(shù)參數(shù)確定函數(shù)調(diào)用
二、函數(shù)重載分析(下)
2.1函數(shù)重載遇上函數(shù)指針
將重載函數(shù)名賦值給函數(shù)指針時
根據(jù)重載規(guī)則挑選與函數(shù)指針參數(shù)列表一致的候選者嚴(yán)格匹配候選者的函數(shù)類型與函數(shù)指針的函數(shù)類型
下面看一段代碼:
#includestdio.h
#includestring.h
intfunc(intx)
returnx;
intfunc(inta,intb)
returna+b;
intfunc(constchar*s)
returnstrlen(s);
typedefint(*PFUNC)(inta);
intmain(intargc,char*argv[])
intc=0;
PFUNCp=func;
c=p(1);
printf("c=%d\n",c);
return0;
}
下面為輸出結(jié)果:
這也就是前面說的通過函數(shù)指針?biāo)赶虻暮瘮?shù)類型參數(shù)列表來進(jìn)行選擇。
注意事項
函數(shù)重載必然發(fā)生在同一個作用域中編譯器需要用參數(shù)列表或函數(shù)類型進(jìn)行函數(shù)選擇無法直接通過函數(shù)名得到重載函數(shù)的入口地址(可以通過指針來獲取)
如下,這段代碼想通過函數(shù)名獲取重載函數(shù)的入口地址:
#includestdio.h
intadd(inta,intb)//int(int,int)
returna+b;
intadd(inta,intb,intc)//int(int,int,int)
returna+b+c;
intmain()
printf("%p\n",add);
printf("%p\n",add);
return0;
}
編譯的時候會報錯,無法確定是哪個函數(shù)。
2.2C++和C的相互調(diào)用
實際工程中C++和C代碼相互調(diào)用是不可避免的C++編譯器能夠兼容C語言的編譯方式C++編譯器會優(yōu)先使用C++編譯的方式extern關(guān)鍵字能強制讓C++編譯器進(jìn)行C方式的編譯
如下:
在Linux環(huán)境下新建一個9-2文件夾,先在文件夾下新建add.c和add.h文件,如下:
add.c:
#include"add.h"
intadd(inta,intb)
returna+b;
}
add.h:
intadd(inta,intb);
通過linux命令cd進(jìn)入9-2文件夾,再將add.c轉(zhuǎn)換成add.o文件,如下所示:
然后在9-2文件夾下建一個main.cpp文件,如下:
mian.cpp:
#includestdio.h
#include"add.h"
intmain()
intc=add(1,2);
printf("c=%d\n",c);
return0;
}
對程序進(jìn)行編譯,發(fā)現(xiàn)程序報錯,沒有定義add()函數(shù),但是函數(shù)確實已經(jīng)定義了,可以使用linux中的nm指令查看add.o里面的信息,打印出來的就是符號表信息,可以看到確實有add。
這個時候就需要使用extern關(guān)鍵字強制讓C++編譯器進(jìn)行C方式的編譯,所以main.cpp就要修改成這樣:
#includestdio.h
extern"C"
#include"add.h"
intmain()
intc=add(1,2);
printf("c=%d\n",c);
return0;
}
這樣編譯就能通過了:
如果在9-2文件中新建一個main.c文件,main.c里面的代碼與main.cpp中的相同。
進(jìn)行編譯,發(fā)現(xiàn)會報錯誤,因為extern關(guān)鍵詞寫法是C++中的,C語言不支持該寫法。那有沒有一種寫法既能被C語言編譯通過,又能讓C++編譯通過呢?且看下面。
2.3使得C代碼只會以C的方式被編譯的解決方案
_cplusplus是C++編譯器內(nèi)置的標(biāo)準(zhǔn)宏定義_cplusplus的意義是確保C代碼以統(tǒng)一的C方式被編譯成目標(biāo)文件
如下:
所以上述代碼可以寫作,main.c和main.cpp均為:
#includestdio.h
#ifdef__cplusplus
extern"C"{
#endif
#include"add.h"
#ifdef__cplusplus
#endif
intmain()
intc=add(1,2);
printf("c=%d\n",c);
return0;
}
這樣程序在C語言和C++的編譯環(huán)境下均能通過,如下:
注意事項
C++編譯器不能以C的方式編譯重載函數(shù)
編譯方式?jīng)Q定函數(shù)名被編譯后的目標(biāo)名
C++編譯方式將函數(shù)名和參數(shù)列表編譯成目標(biāo)名C編譯方式只將函數(shù)名作為目標(biāo)名進(jìn)行編譯
下面通過一個例子說明一下:
intadd(inta,intb)//int(int,int)
returna+b;
intadd(inta,intb,intc)//int(int,int,int)
returna+b+c;
}
將該代碼編譯成目標(biāo)文件,取名為test.oo,然后通過linux中的nm命令查看test.oo中的東西,可以看到test符號表里面有兩個東西T_Z3addii和T_Z3addiii,這就是add函數(shù)被編譯過后的目標(biāo)函數(shù)名,ii表示兩個參數(shù),iii表示三個參數(shù)。
如果采用C方式編譯重載函數(shù),代碼如下:
extern"C"
int
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生產(chǎn)科科長考試題及答案
- 生理學(xué)輸血試題及答案
- 瑞昌小學(xué)畢業(yè)考試題目及答案
- 輔警制度培訓(xùn)課件
- 2026 年初中英語《語法填空》專項練習(xí)與答案 (100 題)
- 2026年深圳中考語文閱讀提分專項試卷(附答案可下載)
- 游戲題目及答案大全
- 2026年深圳中考數(shù)學(xué)中等生提分試卷(附答案可下載)
- 基本邏輯考題題庫及答案
- 2026年深圳中考?xì)v史考場實戰(zhàn)模擬試卷(附答案可下載)
- 2025公文寫作考試真題及答案
- DB64∕T 1279-2025 鹽堿地綜合改良技術(shù)規(guī)程
- 2025年度耳鼻喉科工作總結(jié)及2026年工作計劃
- 2024年執(zhí)業(yè)藥師《藥學(xué)專業(yè)知識(一)》試題及答案
- 統(tǒng)編版語文一年級上冊無紙化考評-趣味樂考 玩轉(zhuǎn)語文 課件
- 高壓氧進(jìn)修課件
- 2025年第三類醫(yī)療器械經(jīng)營企業(yè)質(zhì)量管理自查報告
- 2025無人機物流配送網(wǎng)絡(luò)建設(shè)與運營效率提升研究報告
- 人工智能倫理規(guī)范
- 校園禁毒管理辦法
- 飼料供應(yīng)循環(huán)管理辦法
評論
0/150
提交評論