新聞中心
C++ 當(dāng)中的模板,通常作為處理由于參數(shù)類型不同,而引入的代碼冗余情況。
創(chuàng)新互聯(lián)建站專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、莘縣網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為莘縣等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
首先,我們討論的是函數(shù)模板。
要討論這個問題,我們先討論如果實(shí)現(xiàn)一個通用的加法函數(shù),該怎樣去做?
方法一 :使用C++當(dāng)中的函數(shù)重載
int ADD(const int num1, const int num2) { return (num1+num2); } double ADD(const double num1, const double num2) { return (num1 + num2); } int main() { cout << ADD(1,2) << endl; cout << ADD(1.2,3.4) << endl; system("pause"); return 0; }
關(guān)于這種方法,雖然可以實(shí)現(xiàn)功能,但不得不說,屬于最老實(shí)的做法,代碼的復(fù)用率完全沒有體現(xiàn),而且,在只有返回值類型不相同的情況下,重載是不能夠解決這類問題。代碼維護(hù)起來,也是相當(dāng)麻煩。
方法二:利用C++當(dāng)中的繼承實(shí)現(xiàn)
采用公共基類的方法解決這個問題,要求每實(shí)現(xiàn)一個類,都要特定繼承某一個類,代碼維護(hù)起來更加繁瑣
方法三:宏定義define 解決
宏定義在定義時是不需要考慮類型的,表面上看起來可以實(shí)現(xiàn)這一功能,這一點(diǎn)完全繼承自C語言。代碼如下
#define ADD(a,b) ((a)+(b)) int main() { cout << ADD(1, 2) << endl; cout << ADD(1.2, 3.4) << endl; system("pause"); return 0; }
方便的同時,引入了另一個問題。宏定義是在預(yù)處理過程中就完成的,是不對傳入期中的參數(shù)進(jìn)行合法性檢查的,一定程度上,我們可以說,這種方法是不安全的。
討論了這么多,突然想起了在C語言中有這么一個函數(shù)
由于沒什么經(jīng)驗(yàn)當(dāng)初做這張圖的時候,還是費(fèi)了些功夫。關(guān)于這個函數(shù)的實(shí)現(xiàn),可以在電腦里查一下專家的實(shí)現(xiàn)方法,這里我就不多介紹了,畢竟C++當(dāng)中有著更加方便的工具---------->模板。
在這里先引入一個概念,范性編程,即編寫與類型無關(guān)的邏輯代碼,是代碼復(fù)用的一種手段
現(xiàn)在進(jìn)入正題。認(rèn)識模板之前,首先要提幾個關(guān)鍵字:
Point1: template typename class
其中typename與class的使用,在這里是完全相同的,而且class在模板當(dāng)中也并不是定義類的。注意,在這里,不可以用struct代替class,同樣,我們更加推薦用typename
現(xiàn)在來看具體的使用方法。首先定義一個函數(shù)模板。
templateT ADD(T a, T b) { return (a + b); } int main() { cout << ADD(1, 2) << endl; cout << ADD(1.2, 3.4) << endl; system("pause"); return 0; }
T在這里是我們定義的一種類型。通過函數(shù)模板定義出來的函數(shù),我們把它叫做模板函數(shù),在編譯過程中,如果我們只定義了函數(shù)模板,而沒有定義模板函數(shù),計算機(jī)是不會產(chǎn)生多余的代碼數(shù)據(jù),或者說,計算機(jī)不知道要產(chǎn)生什么樣類型的代碼數(shù)據(jù)。
Point2:
同時,我們也可以在使用函數(shù)模板定義模板函數(shù)時通過"
cout << ADD(1, 2) << endl;
值得注意的是,如果不指定參數(shù)類型,系統(tǒng)將根據(jù)你傳入的變量,選擇默認(rèn)的參數(shù)類型。但是,如果沒有參數(shù),或者傳入的參數(shù)并不是一個類型的話<參照next point>,需要自己聲明,編譯器無法自動給出。
Point3:
除了參數(shù)類型可以作為模板參數(shù)外,變量也可作為模板參數(shù),實(shí)現(xiàn)代碼如下:
templatevoid display() { for (int i = 0; i < size; i++) { cout << i << endl; } } int main() { display<10>(); system("pause"); return 0; }
千萬不要忘記在使用時,對變量進(jìn)行聲明。定義模板時,此時參數(shù)前不需要加class或者typename,而需要加上該變量的類型。
Point4:
模板支持多參數(shù)模板,定義函數(shù)模板時,每個類型參數(shù)前的typename或者class,以及變量的類型均不可省略??梢宰约壕幋a嘗試。
Point5:
函數(shù)模板與重載。
templatevoid display(T a) { cout << a << endl; } template void display(T a,T b) { cout << a << endl; } template //每個函數(shù)模板之前都需要添加template語句 void display(T a) { cout << a << endl; }
在我們定義函數(shù)模板的時候,各函數(shù)模板之間并不構(gòu)成重載,因?yàn)榇藭r,并沒有在內(nèi)存中產(chǎn)生代碼量,而是在我們使用這些函數(shù)模板定義函數(shù)的時候,定義產(chǎn)生的函數(shù)彼此之間構(gòu)成重載。
除了函數(shù)之外,類也有著模板------->類模板
為什么要有類模板呢?和函數(shù)模板一樣,同樣是為了處理相同代碼類型不同的情況。類模板代碼如下:
templateclass Data { public: Data(T d) :_data(d) { } void display() { cout << _data << endl; } protected: T _data; }; int main() { Data d(2); d.display(); system("pause"); return 0; }
關(guān)于類外定義成員函數(shù)的方法:
templateclass Data { public: Data(T d) :_data(d) { } void display(); protected: T _data; }; void Data ::display() { cout << _data << endl; }
當(dāng)然,我現(xiàn)在用的是單文件的定義,如果要在多文件環(huán)境下進(jìn)行定義成員函數(shù),需要在每個函數(shù)之前都加上"template<>",注意 ,是每個!!!
定義函數(shù)時,除了注意這個之外,還有需要注意的是要加上"
當(dāng)然,類模板也支持多參數(shù),定義函數(shù)及實(shí)例化對象是,所有參數(shù)類型都需要注明。
注:受IDE環(huán)境與相關(guān)標(biāo)準(zhǔn)的限制,vs2005,vs2008,vs2010編譯器下,模板代碼不能分離編譯,即模板的.h文件與.cpp文件不能分開進(jìn)行編譯,換句話說,就是無法寫成.h文件與.cpp文件聲明和定義分開這種情況。必須將所有代碼都寫入.h文件,通過include""進(jìn)行引用
這里只介紹了關(guān)于模板的一些基本用法,其他需要注意的,將在下篇統(tǒng)一整理
新聞標(biāo)題:討論關(guān)于C++當(dāng)中的模板實(shí)現(xiàn)(上)
文章網(wǎng)址:http://fisionsoft.com.cn/article/gochcs.html