深入了解C++函數(shù)重載解析策略_第1頁(yè)
深入了解C++函數(shù)重載解析策略_第2頁(yè)
深入了解C++函數(shù)重載解析策略_第3頁(yè)
深入了解C++函數(shù)重載解析策略_第4頁(yè)
深入了解C++函數(shù)重載解析策略_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論