版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第深入了解C++函數(shù)重載解析策略參考《C++PrimerPlus》(第6版)中文版,StephenPrata著,張海龍?jiān)瑖?guó)忠譯,人民郵電出版社。C++使用重載解析策略來(lái)決定為函數(shù)調(diào)用使用哪一個(gè)函數(shù)定義。重載解析過(guò)程大致分為如下三步:
第1步:創(chuàng)建候選函數(shù)列表,只要求函數(shù)名一樣即可,對(duì)函數(shù)特征標(biāo)以及是否為模板函數(shù)無(wú)要求;
第2步:在上一步的基礎(chǔ)上創(chuàng)建可行函數(shù)列表,包含特征標(biāo)完全匹配的常規(guī)函數(shù)或模板函數(shù)、以及實(shí)參隱式轉(zhuǎn)換后完全匹配的常規(guī)函數(shù)或模板函數(shù),這些都是參數(shù)數(shù)目正確的函數(shù);
第3步:在上一步的基礎(chǔ)上確定最佳匹配函數(shù),若有則使用它,若沒(méi)有則該函數(shù)調(diào)用失敗。
下面以一個(gè)例子來(lái)說(shuō)明這個(gè)重載過(guò)程:
//全部函數(shù)原型
voidmay(int);//原型#1
floatmay(float,float=3);//原型#2
voidmay(char);//原型#3
char*may(constchar*);//原型#4
charmay(constchar//原型#5
templateclassTvoidmay(constT//原型#6
templateclassTvoidmay(T*);//原型#7
voidmay(char,double);//原型#8
voidmbk(float);//原型#9
charmkk(int,char);//原型#10
intmck(char);//原型#11
doublemyk(float);//原型#12
voidmpk(char);//原型#13
//函數(shù)調(diào)用
may('B');
//函數(shù)定義
重載第1步:創(chuàng)建候選函數(shù)列表。即函數(shù)名稱(chēng)為may的常規(guī)函數(shù)和模板函數(shù),候選函數(shù)列表如下:
//重載第1步:創(chuàng)建候選函數(shù)列表
voidmay(int);//原型#1
floatmay(float,float=3);//原型#2
voidmay(char);//原型#3
char*may(constchar*);//原型#4
charmay(constchar//原型#5
templateclassTvoidmay(constT//原型#6
templateclassTvoidmay(T*);//原型#7
voidmay(char,double);//原型#8
重載第2步:創(chuàng)建可行函數(shù)列表。由于整數(shù)類(lèi)型char不能被隱式地轉(zhuǎn)換為指針類(lèi)型char*,因此函數(shù)#4和函數(shù)#7都被排除,而函數(shù)#8因?yàn)閰?shù)數(shù)目不匹配也會(huì)被排除。進(jìn)行完全匹配時(shí),C++允許下表這些無(wú)關(guān)緊要的轉(zhuǎn)換,表中Type表示任意類(lèi)型,例如char到constchar的轉(zhuǎn)換也包含在內(nèi),表中Type(argument-list)意味著用作實(shí)參的函數(shù)名和用作形參的函數(shù)指針只要返回類(lèi)型和參數(shù)列表相同,就是匹配的。
實(shí)參類(lèi)型形參類(lèi)型TypeTypeTypeTypeType[]Type*Type(argument-list)Type(*)(argument-list)TypeconstTypeTypevolatileTypeType*constType*Type*volatileType*
根據(jù)此表可知,剩下的函數(shù)中包含特征標(biāo)完全匹配的常規(guī)函數(shù)#3和#5、特征標(biāo)完全匹配的模板函數(shù)#6(此時(shí)T可以被實(shí)例化為char)、實(shí)參隱式轉(zhuǎn)換后完全匹配的常規(guī)函數(shù)#1和#2??尚泻瘮?shù)列表如下:
//重載第2步:創(chuàng)建可行函數(shù)列表
voidmay(int);//原型#1
floatmay(float,float=3);//原型#2
voidmay(char);//原型#3
charmay(constchar//原型#5
templateclassTvoidmay(constT//原型#6
重載第3步:確定最佳匹配函數(shù)。通常,從最佳到最差的順序如下所述:
特征標(biāo)完全匹配;類(lèi)型需經(jīng)隱式提升轉(zhuǎn)換,例如char和short自動(dòng)轉(zhuǎn)換為int,float自動(dòng)轉(zhuǎn)換為double;類(lèi)型需經(jīng)隱式標(biāo)準(zhǔn)轉(zhuǎn)換,例如int轉(zhuǎn)換為char,long轉(zhuǎn)換為double;類(lèi)型需經(jīng)隱式自定義轉(zhuǎn)換,例如類(lèi)中用戶(hù)定義的類(lèi)型轉(zhuǎn)換。
依此規(guī)則,函數(shù)#3和函數(shù)#5、函數(shù)#6都是特征標(biāo)完全匹配的最佳匹配函數(shù),函數(shù)#1需經(jīng)隱式提升轉(zhuǎn)換,函數(shù)#2需經(jīng)隱式標(biāo)準(zhǔn)轉(zhuǎn)換,由此各函數(shù)最佳匹配程度為:(#3,#5,#6)#1#2。當(dāng)特征標(biāo)完全匹配時(shí),又有如下規(guī)則:
指向非const數(shù)據(jù)的指針和引用優(yōu)先與形參為非const指針和引用的函數(shù)匹配;優(yōu)先與非模板函數(shù)匹配;同為模板函數(shù)時(shí),優(yōu)先與較具體的模板函數(shù)匹配。
依此規(guī)則,非模板函數(shù)#3和#5最佳匹配程度要高于模板函數(shù)#6,即各函數(shù)最佳匹配程度為:(#3,#5)#6#1#2。最終出現(xiàn)了兩個(gè)最佳匹配函數(shù)#3和#5,因此該函數(shù)調(diào)用失敗,編譯器將報(bào)錯(cuò)。
//重載第3步:確定最佳匹配函數(shù)
voidmay(char);//原型#3
charmay(constchar//原型#5
下面展開(kāi)來(lái)說(shuō)上述幾條完全匹配時(shí)的規(guī)則。
第1條:指向非const數(shù)據(jù)的指針和引用優(yōu)先與形參為非const指針和引用的函數(shù)匹配,這一點(diǎn)需明確,const和非const之間的區(qū)別只適用于指針和引用。下面4個(gè)函數(shù)都與函數(shù)調(diào)用是完全匹配的:
//函數(shù)原型
voidrecycle(int);//原型#1
voidrecycle(constint);//原型#2
voidrecycle(int//原型#3
voidrecycle(constint//原型#4
//函數(shù)調(diào)用
intx=5;
recycle(x);
//函數(shù)定義
如果這4個(gè)函數(shù)同時(shí)存在,則無(wú)法完成重載,編譯器會(huì)報(bào)多義性匹配的錯(cuò)誤;如果只存在函數(shù)#1與#2,則無(wú)法完成重載,編譯器會(huì)報(bào)重復(fù)定義的錯(cuò)誤;如果只存在函數(shù)#1與#3,則無(wú)法完成重載,編譯器會(huì)報(bào)多義性匹配的錯(cuò)誤;如果只存在函數(shù)#1與#4,則無(wú)法完成重載,編譯器會(huì)報(bào)多義性匹配的錯(cuò)誤;如果只存在函數(shù)#2與#3,則無(wú)法完成重載,編譯器會(huì)報(bào)多義性匹配的錯(cuò)誤;如果只存在函數(shù)#2與#4,則無(wú)法完成重載,編譯器會(huì)報(bào)多義性匹配的錯(cuò)誤;如果只存在函數(shù)#3與#4,則函數(shù)調(diào)用時(shí)編譯器將會(huì)選擇#3。
第2條:優(yōu)先與非模板函數(shù)匹配,這一點(diǎn)比較簡(jiǎn)單,當(dāng)完全匹配的函數(shù)中,一個(gè)是非模板函數(shù),另一個(gè)是模板函數(shù)時(shí),非模板函數(shù)將優(yōu)于模板函數(shù),顯式具體化、顯式實(shí)例化、隱式實(shí)例化都屬于模板函數(shù)。
第3條:同為模板函數(shù)時(shí),優(yōu)先與較具體的模板函數(shù)匹配,找出最具體的模板的規(guī)則被稱(chēng)為函數(shù)模板的部分排序規(guī)則(partialorderingrules)。這意味著顯式具體化優(yōu)先于常規(guī)模板函數(shù),都為常規(guī)模板函數(shù)時(shí),編譯器優(yōu)先選擇實(shí)例化時(shí)類(lèi)型轉(zhuǎn)換更少的那一個(gè)。以下面的程序?yàn)槔?,調(diào)用方式recycle(ink)既與模板#1匹配,此時(shí)Type將被解釋為blot*,也與模板#2匹配,此時(shí)Type將被解釋為blot,因此將這兩個(gè)隱式實(shí)例recycleblot*(blot*)和recycleblot(blot*)發(fā)送到可行函數(shù)池中。在選擇最佳匹配函數(shù)時(shí),#2被認(rèn)為是更具體的,因?yàn)樗呀?jīng)顯式地指出,函數(shù)參數(shù)是指向Type的指針,相比于#1,它對(duì)類(lèi)型的要求更加地具體,在生成過(guò)程中所需要的轉(zhuǎn)換更少,因此調(diào)用方式recycle(ink)實(shí)際會(huì)匹配版本#2。
//兩個(gè)常規(guī)模板函數(shù)
templateclassTypevoidrecycle(Typet);//原型#1
templateclassTypevoidrecycle(Type*t);//原型#2
//調(diào)用程序包含如下代碼
structblot{inta;charb[10];};
blotink={25,"spots"};
recycle(ink);//使用版本#2
//函數(shù)定義
部分排序規(guī)則的另一個(gè)示例程序如下,它與上一個(gè)例子有異曲同工之妙。由于模板#2做了特定的假設(shè):數(shù)組內(nèi)容是指針,對(duì)類(lèi)型的要求更加地具體,因此在調(diào)用時(shí)第一個(gè)參數(shù)若傳入指針數(shù)組pt,則將實(shí)際匹配函數(shù)#2。
//兩個(gè)常規(guī)模板函數(shù)
templatetypenameT
voidShowArray(Tarr[],intn);//原型#1
templatetypenameT
voidShowArray(T*arr[],intn);//原型#2
//調(diào)用程序包含如下代碼
intthings[6]={13,31,103,301,310,130};
int*pt[3]={things[0],things[2],things[4]};
ShowArray(things,6);//使用版本#1
ShowArray(pt,3);//使用版本#2
//函數(shù)定義
將有多個(gè)參數(shù)的函數(shù)調(diào)用與有多個(gè)參數(shù)的原型進(jìn)行匹配時(shí),編譯器必須考慮所有參數(shù)的匹配情況。如果找到比其他可行函數(shù)都合適的函數(shù),則選擇該函數(shù)。一個(gè)函數(shù)要比其他函數(shù)都合適,其所有參數(shù)的匹配程度都必須不比其他函數(shù)差,同時(shí)至少有一個(gè)參數(shù)的匹配程度比其他函數(shù)都高。
在有些情況下,可通過(guò)編寫(xiě)合適的函數(shù)調(diào)用,來(lái)引導(dǎo)編譯器做出程序員期望的選擇。如下所示,其中模板函數(shù)返回兩個(gè)值中較小的一個(gè),非模板函數(shù)返回兩個(gè)值中絕對(duì)值較小的那個(gè)。第一次調(diào)用時(shí)根據(jù)重載解析策略選擇了非模板函數(shù)#2;第二次調(diào)用時(shí)根據(jù)重載解析策略選擇了模板函數(shù)#1的double版本,屬于模板函數(shù)的隱式實(shí)例化;第三次調(diào)用的指出,編譯器應(yīng)該選擇模板函數(shù),此時(shí)編譯器會(huì)查看調(diào)用函數(shù)時(shí)的實(shí)參類(lèi)型來(lái)進(jìn)行實(shí)例化,也屬于模板函數(shù)的隱式實(shí)例化;第四次調(diào)用的int顯式指出,編譯器應(yīng)該使用模板函數(shù)的int實(shí)例化版本,此時(shí)屬于模板函數(shù)的顯式實(shí)例化。
#includeiostream
//函數(shù)#1
templateclassT
Tlesser(Ta,Tb)
returnaba:b;
//函數(shù)#2
intlesser(inta,intb)
a=a0-a:a;
b=b0-b:b;
returnaba:b;
//函數(shù)調(diào)用
intmain()
usingnamespacestd;
intm=20;
intn=-30;
doublex=15.5;
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 外勤機(jī)械工安全生產(chǎn)意識(shí)競(jìng)賽考核試卷含答案
- 成品礦運(yùn)送工崗前基礎(chǔ)操作考核試卷含答案
- 信息通信網(wǎng)絡(luò)線務(wù)員安全意識(shí)測(cè)試考核試卷含答案
- 抽紗挑編工保密能力考核試卷含答案
- 2025年中原科技學(xué)院馬克思主義基本原理概論期末考試模擬題附答案
- 2024年灤縣輔警招聘考試真題匯編附答案
- 2024年重慶工程職業(yè)技術(shù)學(xué)院輔導(dǎo)員招聘?jìng)淇碱}庫(kù)附答案
- 2024年鄭州信息科技職業(yè)學(xué)院輔導(dǎo)員考試筆試真題匯編附答案
- 企業(yè)信息化安全防護(hù)與應(yīng)急處置實(shí)務(wù)操作手冊(cè)
- 2025四川省成都市公務(wù)員考試數(shù)量關(guān)系專(zhuān)項(xiàng)練習(xí)題及參考答案1套
- 中深度鎮(zhèn)靜紅外線全身熱療方法課件
- 第四單元地理信息技術(shù)的應(yīng)用課件 【高效課堂+精研精講】高中地理魯教版(2019)必修第一冊(cè)
- 魯科版高中化學(xué)必修一教案全冊(cè)
- 管理養(yǎng)老機(jī)構(gòu) 養(yǎng)老機(jī)構(gòu)的服務(wù)提供與管理
- 提高隧道初支平整度合格率
- 2022年環(huán)保標(biāo)記試題庫(kù)(含答案)
- 2023年版測(cè)量結(jié)果的計(jì)量溯源性要求
- 建筑能耗與碳排放研究報(bào)告
- GB 29415-2013耐火電纜槽盒
- 中國(guó)古代經(jīng)濟(jì)試題
- 真空采血管的分類(lèi)及應(yīng)用及采血順序課件
評(píng)論
0/150
提交評(píng)論