999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

C++函數(shù)模板的模板參數(shù)類型轉(zhuǎn)換技術(shù)

2014-11-06 14:08:08何遠(yuǎn)強(qiáng)李全艷彭海平龔紅仿
科技創(chuàng)新導(dǎo)報(bào) 2014年10期

何遠(yuǎn)強(qiáng)++李全艷++彭海平++龔紅仿

摘 要:模板是C++為用戶提供的一種功能非常強(qiáng)大的、能方便的實(shí)現(xiàn)類屬編程的工具。該文討論了利用重載函數(shù)模板的方法實(shí)現(xiàn)模板參數(shù)類型的顯式轉(zhuǎn)換機(jī)制,并闡明了在實(shí)際應(yīng)用中必須注意的問題。

關(guān)鍵詞:C++ 函數(shù)模板 重載函數(shù) 模板參數(shù) 類型轉(zhuǎn)換

中圖分類號(hào):TP312 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1674-098X(2014)04(a)-0019-02

模板是C++為用戶提供的一種功能非常強(qiáng)大的、能方便的實(shí)現(xiàn)類屬編程的工具,它允許用戶構(gòu)造類屬函數(shù)——模板函數(shù)。但在實(shí)際編程中,我們并不是直接定義模板函數(shù),而是定義一類函數(shù)的抽象——函數(shù)模板,它以任意的數(shù)據(jù)類型T為參數(shù)及函數(shù)返回值,用將T實(shí)例化的模板參數(shù)再實(shí)例化函數(shù)模板,所得的函數(shù)就是模板函數(shù)。因而,函數(shù)模板并不是一個(gè)完全的函數(shù),而是代表一類函數(shù),只有用模板參數(shù)實(shí)例化后成為模板函數(shù),才能完成具體的函數(shù)功能。

1 問題的提出

在模板函數(shù)實(shí)例化為函數(shù)模板時(shí),盡管模板參數(shù)T可以實(shí)例化成各種類型,但是采用模板參數(shù)T的各參數(shù)之間必須保持完全一致的類型。我們先看下面的例子:

template

T max(T x,T y)

{ return (x>y)?x:y;

}

void main()

{ int i=10;

char c=a;

float f=4.374;

cout<

cout<

cout<

cout<

cout<

cout<

cout<

}

在上面的例子中,定義的函數(shù)模板是比較兩個(gè)數(shù)的大小,數(shù)據(jù)類型既可以是系統(tǒng)預(yù)定義類型,也可以是用戶自定義類型。這里,由函數(shù)模板生成了三個(gè)模板函數(shù),分別是用模板實(shí)參int、char、float將類型參數(shù)T實(shí)例化而得。

我們可以看出,只有當(dāng)參數(shù)類型完全一致時(shí),得到的模板函數(shù)才是正確的。當(dāng)參數(shù)類型不一致時(shí),例如 max(i,c),系統(tǒng)將提醒我們找不到與max(int,char)相匹配的函數(shù)定義。然而,在C++中,int類型和char類型之間、flot類型與int類型之間、float類型與double類型之間等,都可以隱式轉(zhuǎn)換,而且這種轉(zhuǎn)換是非常普遍的。因而,完全可以把函數(shù)max(int,char)認(rèn)為是函數(shù)max(int,int)。但是,模板類型沒有這種識(shí)別能力,不具有隱式類型轉(zhuǎn)換的功能。

在實(shí)際編程的過程中,經(jīng)常會(huì)使用函數(shù)模板解決功能相同的一類問題,既可以大大減少程序代碼、避免重復(fù)的定義,又可以增強(qiáng)程序的清晰性和可讀性,這就涉及到如何實(shí)現(xiàn)模板參數(shù)類型轉(zhuǎn)換機(jī)制的問題。

2 重載模板函數(shù)

解決這個(gè)問題的方法是允許函數(shù)模板參與重載,即可以用非模板函數(shù)重載一個(gè)同名的函數(shù)模板,有兩種表述方式:

其一,利用函數(shù)模板的函數(shù)體。非模板函數(shù)對(duì)函數(shù)模板的重載定義是通過借用函數(shù)模板的函數(shù)體。需要定義重載時(shí),只需聲明,不用給出函數(shù)體,當(dāng)執(zhí)行此重載版本時(shí)會(huì)自動(dòng)調(diào)用函數(shù)模板的函數(shù)體。例如,在上例中,可以作如下聲明:

int max(int,int);

這樣就完成了重載聲明,此重載函數(shù)雖然借用了函數(shù)模板的函數(shù)體,但它支持?jǐn)?shù)據(jù)類型間的隱式轉(zhuǎn)換。經(jīng)過這樣和重載定義后,使得max(int,char), max(char,int), max(float,int), max(int,float), max(double,int), max(double,float)等一系列函數(shù)變成為合理的和正確的調(diào)用。

其二,重新定義函數(shù)體。對(duì)于要重新定義函數(shù)體的重載函數(shù),所帶參數(shù)的類型可以隨意,就像一般的重載函數(shù)一樣定義。例如,在上例中,比較兩個(gè)字符串的大小,可以重栽定義如下:

char *max(char *x,char *y)

{return(strcmp(x,y)>0)?x:y;}

但是,在一個(gè)實(shí)際的函數(shù)調(diào)用時(shí),它既可以和一個(gè)重載函數(shù)相匹配或是參數(shù)隱式轉(zhuǎn)換后與某一重載函數(shù)相匹配,又可以與某一模板函數(shù)相匹配。究竟調(diào)用哪一個(gè)函數(shù),需按照一定的規(guī)則安排先后次序。這些規(guī)則就是函數(shù)模板與同名的非模板函數(shù)的重載在調(diào)用時(shí)均需遵循的約定:

(1)首先尋找一個(gè)參數(shù)完全匹配的函數(shù),如果找到了就調(diào)用它。

(2)在(1)失敗后,尋找一個(gè)函數(shù)模板,使其實(shí)例化,產(chǎn)生一個(gè)匹配的模板函數(shù),若找到了,就調(diào)用它。

(3)在上面均失敗后,再試一試低一級(jí)的對(duì)函數(shù)的重載方法,即通過類型轉(zhuǎn)換可產(chǎn)生參數(shù)匹配,若找到了,就調(diào)用它。

(4)若以上均失敗,則得出是一個(gè)錯(cuò)誤調(diào)用的判定。

我們看一個(gè)重載函數(shù)模板的例子,根據(jù)上面的規(guī)則來(lái)判斷各函數(shù)的調(diào)用情況:

#include

#include

template //定義函數(shù)模板

T max(T x,T y)

{ cout<<"This is a template function! The max is: ";

return (x>y)?x:y;

}

class point //定義類類型

{ float x,y;

public:

point(float x=0,float y=0);

float getx(){return x;}

float gety(){return y;}

float point_sqrt();

friend int operator>(point px,point py); //用友元重載”>”運(yùn)算符

}

//point類成員函數(shù)定義

point::point(float x,float y)

{ point::x=x;

point::y=y;

}

float point::point_sqrt()

{ return sqrt(x*x+y*y);}

int operator>(point px,point py)

{ if (px.point_sqrt()>py.point_sqrt()) return 1;

else return 0;

}

//重載函數(shù)定義

int max(int x,int y) //重新定義函數(shù)體

{ cout<<"This is the overload function with int,int! The max is: ";

return (x>y)?x:y;

}

char max(int x,char y) //重新定義函數(shù)體

{cout<<"This is the overload function with int,char! The max is:";

return (x>y)?x:y;

}

void func(int i,char c,float f)

{cout<

cout<

cout<

cout<

cout<

cout<

}

void main()

{ int i; char c; float f;

…… //輸入i,c,f

func(i,c,f); //調(diào)用func函數(shù)實(shí)現(xiàn)模板參數(shù)類型的轉(zhuǎn)換

point pa(2,5),pb(3,4),pc;

pc=max(pa,pb); //調(diào)用模板函數(shù)用point類類型實(shí)例化

cout<<"("<

cout<

}

我們分析上面的程序,在主函數(shù)main()中,調(diào)用func(i,c,f)函數(shù)。在func(i,c,f)函數(shù)中調(diào)用max(i,i)時(shí),由于兩個(gè)參數(shù)均為整型,按照規(guī)則,首先查找完全匹配的函數(shù)進(jìn)行調(diào)用,因此它調(diào)用的是int max(int,int)重載版本。

調(diào)用max(c,c)時(shí),首先沒有找到完全匹配的函數(shù),因此對(duì)函數(shù)模板進(jìn)行實(shí)例化,它應(yīng)該調(diào)用函數(shù)模板的實(shí)例化版本:char max(char,char)。

調(diào)用max(i,c)時(shí),首先,查找完全匹配的版本,它與char max(int,char)完全匹配,因此就調(diào)用這個(gè)重載函數(shù)版本。

調(diào)用max(c,i)時(shí),既找不到完全匹配的函數(shù)版本,又找不到能與之匹配的模板函數(shù),所以只好試第三步,看對(duì)參數(shù)類型轉(zhuǎn)換后能否有匹配的,將max(c,i)中的c轉(zhuǎn)換成int型后與int max(int,int)匹配,因此就執(zhí)行這個(gè)重載函數(shù)版本。

調(diào)用max(f,f)時(shí),找不到與它完全匹配的函數(shù),那么,函數(shù)模板實(shí)例化后的版本中的模板函數(shù)float max(float,float)可與它匹配,因此它就調(diào)用模板函數(shù)。

調(diào)用max(f,i)時(shí),既找不到完全匹配的函數(shù),又找不到合適的模板函數(shù),只好對(duì)其參數(shù)進(jìn)行類型轉(zhuǎn)換,其中f轉(zhuǎn)換為int類型后,與int max(int,int)相匹配,因此就調(diào)用這個(gè)重載函數(shù)版本。

在主函數(shù)main()中,調(diào)用max(pa,pb)函數(shù),由于兩個(gè)參數(shù)均為用戶自定義point類類型,找不到與它完全匹配的函數(shù),那么,函數(shù)模板實(shí)例化后的版本中的模板函數(shù)point max(point,point)可與它匹配,因此它就調(diào)用模板函數(shù)。

在point類類型定義中,定義兩點(diǎn)分別到原點(diǎn)(0,0)的距離,作為兩點(diǎn)比較大小的依據(jù),如某點(diǎn)離原點(diǎn)越遠(yuǎn),則認(rèn)為該點(diǎn)越大。point類的成員函數(shù)point_sqrt()求點(diǎn)到原點(diǎn)的距離,友員函數(shù)int operator>(point px,point py)用來(lái)重載”>”運(yùn)算符,判斷point類對(duì)象的大小。

3 需要注意的問題

其一,利用模板函數(shù)的函數(shù)體重載定義非模板函數(shù)時(shí),只需聲明,不用給出函數(shù)體,且聲明時(shí)必須注意各模板參數(shù)的實(shí)參類型必須一致。如:int max(int,int)等。

其二,重新定義重載函數(shù)體時(shí),特別要注意避免產(chǎn)生預(yù)期的和非預(yù)期的二義性。例如,若對(duì)函數(shù)模板有這樣兩個(gè)重載函數(shù):

int max(int,int); //重載聲明

char max(int x,char y) //重新定義

{ …}

當(dāng)進(jìn)行函數(shù)調(diào)用時(shí)有這樣一個(gè)調(diào)用形式:max(i,f);

此處i為int類型,f為float類型,系統(tǒng)無(wú)法決定該調(diào)用與這兩個(gè)重載函數(shù)中的哪一個(gè)相聯(lián)系,既可以將f轉(zhuǎn)換成int類型后調(diào)用max(int,int),又可以將f轉(zhuǎn)換成char類型后調(diào)用max(int,char)。這個(gè)函數(shù)調(diào)用就存在著二義性。

4 結(jié)語(yǔ)

該文討論了利用重載函數(shù)模板的方法實(shí)現(xiàn)模板參數(shù)類型的顯式轉(zhuǎn)換機(jī)制,并說明了在實(shí)際應(yīng)用中必須注意的問題。事實(shí)上,在實(shí)際編程中,情況可能更復(fù)雜些,如用戶自定義結(jié)構(gòu)類型、聯(lián)合類型、類類型參數(shù)的轉(zhuǎn)換等,均需視具體情況給出適當(dāng)?shù)妮o助函數(shù)以實(shí)現(xiàn)模板參數(shù)類型的轉(zhuǎn)換。

參考文獻(xiàn)

[1] 王燕.面向?qū)ο竦睦碚撆cC++實(shí)踐[M].北京:清華大學(xué)出版社,2002.

[2] 錢能.C++程序設(shè)計(jì)教程[M].北京:清華大學(xué)出版社,2009.

[3] 鄭阿奇.Visual c++教程[M].北京:機(jī)械工業(yè)出版社,2008.

[4] [美]H.M.Deitel,P.J.Deitel著,C++大學(xué)教程[M].2版.邱仲潘,譯.北京:電子工業(yè)出版社,2003.

主站蜘蛛池模板: 美女高潮全身流白浆福利区| 伊伊人成亚洲综合人网7777| 亚洲精品制服丝袜二区| 国产成+人+综合+亚洲欧美| 伊人网址在线| 国产偷倩视频| 欧美精品啪啪| 国产欧美日韩一区二区视频在线| 成人国产精品2021| 中文纯内无码H| 91色在线观看| 亚洲综合精品香蕉久久网| 久久精品电影| 51国产偷自视频区视频手机观看| 亚洲欧美另类中文字幕| 高潮爽到爆的喷水女主播视频| 制服丝袜亚洲| 天堂网亚洲系列亚洲系列| 欧美福利在线播放| av色爱 天堂网| 亚洲精品在线91| 亚洲成人精品久久| 亚洲日韩精品欧美中文字幕 | 77777亚洲午夜久久多人| 97在线碰| 国产精品手机视频| 久久无码av三级| 无码aaa视频| 一级毛片免费的| 久久久91人妻无码精品蜜桃HD| 色婷婷狠狠干| 国产成人亚洲日韩欧美电影| 九九热精品在线视频| 青青久视频| 亚洲无码视频图片| 国产成人在线无码免费视频| 广东一级毛片| 国产免费好大好硬视频| 91精品久久久无码中文字幕vr| yy6080理论大片一级久久| 国产h视频在线观看视频| 久久婷婷国产综合尤物精品| 99尹人香蕉国产免费天天拍| 国产激爽大片高清在线观看| 国产精品深爱在线| 久久影院一区二区h| 91免费国产高清观看| 波多野结衣亚洲一区| 先锋资源久久| 亚洲AV无码一区二区三区牲色| 中国美女**毛片录像在线| Aⅴ无码专区在线观看| 欧美精品在线免费| 亚洲精品在线影院| 亚洲精品免费网站| 亚洲精品波多野结衣| 91在线激情在线观看| 日本午夜三级| 午夜精品一区二区蜜桃| 国产精品偷伦在线观看| 99这里只有精品6| 精品国产网| 免费国产黄线在线观看| 青青草原偷拍视频| 成年人免费国产视频| 国产精品理论片| 成年网址网站在线观看| 久久国产乱子| 欧洲亚洲一区| 国产综合精品日本亚洲777| 免费毛片全部不收费的| 永久毛片在线播| 九九这里只有精品视频| 尤物特级无码毛片免费| 久久精品只有这里有| 99re热精品视频国产免费| a在线观看免费| 欧美精品成人| 成人日韩欧美| 亚洲第一极品精品无码| 好吊妞欧美视频免费| 全午夜免费一级毛片|