柚子快報(bào)邀請(qǐng)碼778899分享:c語(yǔ)言 探索C嘎嘎:模版初階
柚子快報(bào)邀請(qǐng)碼778899分享:c語(yǔ)言 探索C嘎嘎:模版初階
前言:
? 小編在前文講述了C++的內(nèi)存管理,下面我們來(lái)開始繼續(xù)探索C++,開啟C++又一個(gè)重要的內(nèi)容,模版初階的詳解,代碼時(shí)間到!
目錄
1.泛型編程
1.1.引子
1.2.泛型編程
2.函數(shù)模版
2.1.函數(shù)模版的概念
2.2.函數(shù)模版的格式
2.3.函數(shù)模版的原理
2.4.函數(shù)模版的實(shí)例化
?2.4.1.隱式實(shí)例化
2.4.2.顯示實(shí)例化
2.5.函數(shù)模版的匹配原則
3.類模版
3.1.類模版的定義格式
3.2.類模版的實(shí)例化
4.總結(jié) ???????
正文:
1.泛型編程
1.1.引子
? 在講述泛型編程之前,小編先說(shuō)一個(gè)例子來(lái)幫助各位讀者朋友等會(huì)更好的去了解泛型編程,交換函數(shù)想必各位讀者朋友都非常清楚,我們?cè)贑語(yǔ)言階段就多次寫過(guò)交換函數(shù),小編也在二叉樹那篇文章也寫過(guò)交換函數(shù),交換函數(shù)是幫我們?nèi)ソ粨Q兩個(gè)數(shù),只不過(guò)這兩個(gè)數(shù)的類型一般是一致的,就比如整形就得和整形進(jìn)行交換,字符型就是要和字符型進(jìn)行交換,就比如下面代碼所示:
void swap(int& a, int& b)
{
int c = a;
a = b;
b = c;
}
void swap(float& a, float& b)
{
float c = a;
a = b;
b = c;
}
void swap(char& a, char& b)
{
char c = a;
a = b;
b = c;
}
? 當(dāng)我們?cè)趯懸粋€(gè)項(xiàng)目的時(shí)候,那個(gè)項(xiàng)目既有整形的交換,浮點(diǎn)型的交換,字符型交換等等,這就意味著我們需要寫三個(gè)重載的函數(shù)來(lái)完成交換函數(shù),這樣就體現(xiàn)不出來(lái)C++的簡(jiǎn)介美了,只會(huì)讓我們?cè)黾訉懘a的量,而且還有代碼的可維護(hù)性比較低,一步錯(cuò)步步錯(cuò),這就得不償失了,于是C++就推出了一個(gè)好用的功能,它就是模版,通過(guò)寫模版我們就可以實(shí)現(xiàn)出交換函數(shù),一個(gè)模版便可以解決上面三個(gè)函數(shù)的問(wèn)題2,在具體講解模版之前,小編先給各地讀者朋友簡(jiǎn)單介紹一下泛型編程。
1.2.泛型編程
? 如果在C++中,也能存在一個(gè)摸具,通過(guò)給這個(gè)模具不斷的添加材料(類型),來(lái)獲得不同材料的鑄件(即生成相同類型的代碼),那就會(huì)節(jié)省很多開支,巧的就是前人已經(jīng)將樹栽好(模具已經(jīng)建立),我們僅需再次乘涼即可。泛型編程就是編寫與類型無(wú)關(guān)的通用代碼,是代碼復(fù)用的一種手段,我們今日所講的模版,便就是泛型編程的基礎(chǔ),現(xiàn)在我們還不能完全去了解泛型編程,因?yàn)槲覀儗W(xué)的還沒(méi)有那么深,現(xiàn)在我們僅需知道模版是泛型編程的基礎(chǔ)即可,下面小編將會(huì)分兩步進(jìn)行模版的講述,一個(gè)是函數(shù)的模版,一個(gè)是類的模版,下面,系好安全帶,準(zhǔn)備出發(fā)!
2.函數(shù)模版
2.1.函數(shù)模版的概念
? 函數(shù)模版其實(shí)代表了一個(gè)函數(shù)家族,該函數(shù)模版與類型無(wú)關(guān),在使用被參數(shù)化,根據(jù)實(shí)參類型產(chǎn)生函數(shù)的特定;類型版本
2.2.函數(shù)模版的格式
? 下面小編就展示一下我們?nèi)绾稳懞瘮?shù)模版,如下所示:
template
返回值類型 函數(shù)名(參數(shù)列表){} //這里需要注意,此時(shí)上面的typename也可以寫成class,怎么方便怎么來(lái)
? 以上便就是函數(shù)模版的寫法,小編也在代碼頁(yè)寫了,此時(shí)的typename也可以寫成class,根據(jù)自己的習(xí)慣自己來(lái)就好,小編就喜歡使用class,可能現(xiàn)在很多讀者朋友知道了用法,但是不知道如何實(shí)踐,不要著急,下面小編就給各位讀者朋友展示一下交換函數(shù)的模版應(yīng)該怎么寫。
template
void swap(T& x, T& y)
{
T m = x;
x = y;
y = m;
}
? 上面便就是交換函數(shù)的模版,通過(guò)上面的書寫,小編認(rèn)為可以快速幫助讀者朋友認(rèn)識(shí)到函數(shù)模版的使用,下面小編給各位讀者朋友講述一下函數(shù)模版實(shí)現(xiàn)的原理。
2.3.函數(shù)模版的原理
? 函數(shù)模版其實(shí)和現(xiàn)實(shí)生活中的藍(lán)圖差不多,它本身并不是函數(shù),是編譯器用使用方式產(chǎn)生特定的具體類型的模具,所以其實(shí)模版就是幫助我們把本來(lái)我們自己要重復(fù)干的活交給了編譯器來(lái)做,簡(jiǎn)單來(lái)說(shuō),我們通過(guò)模版讓編譯器變成了牛馬,其中的過(guò)程如下圖所示:
? ?在編譯器進(jìn)行編譯的階段,對(duì)于函數(shù)模版的使用,編譯器需要根據(jù)傳入的實(shí)參類型來(lái)推演生成對(duì)應(yīng)類型的函數(shù)以供調(diào)用。就比如:當(dāng)用double類型使用函數(shù)模版的時(shí)候,編譯器會(huì)對(duì)類型進(jìn)行推演,進(jìn)而確認(rèn)T就是double,然后會(huì)產(chǎn)生一份專門處理double的代碼,對(duì)于字符型,整形什么的也是這種情況,這就是函數(shù)模版的原理,簡(jiǎn)單來(lái)說(shuō),我們只要寫好了模版,編譯器會(huì)自動(dòng)識(shí)別我們傳遞的類型從而把T轉(zhuǎn)換成對(duì)應(yīng)的類型,這個(gè)時(shí)候可能就有讀者朋友會(huì)問(wèn)了,對(duì)于上面小編所寫的交換函數(shù)代碼,倘若我填的第一個(gè)數(shù)是整形,第二個(gè)數(shù)是浮點(diǎn)型會(huì)有怎樣的情況?不要著急,這涉及到了小編后面將會(huì)講述的知識(shí)點(diǎn),下面繼續(xù)往后出發(fā)嘍!
2.4.函數(shù)模版的實(shí)例化
? 用不同的類型使用函數(shù)模版的時(shí)候,稱為函數(shù)模版的實(shí)例化,函數(shù)模版的實(shí)例化可以分為隱式實(shí)例化和顯示實(shí)例化,現(xiàn)在我們先來(lái)進(jìn)行前者的講述。
?2.4.1.隱式實(shí)例化
? 對(duì)于隱式實(shí)例化,說(shuō)白了其實(shí)就是讓編譯器自己去識(shí)別此時(shí)的類型是什么,然后再把T轉(zhuǎn)換成相應(yīng)的類型即可,下面小編就用加法函數(shù)來(lái)給各位讀者朋友舉例,如下代碼所示:
template
T Add(T x, T y)
{
return x + y;
}
int main()
{
int a = 12, b = 13;
double c = 11.1, d = 12.2;
int m = Add(a,b);
Add(c, d);
}
? 以上就是函數(shù)模版的隱式實(shí)例化,其實(shí)隱式實(shí)例化可以理解為我們什么也不需要做,讓編譯器幫我們?nèi)プ鼍秃昧耍贿^(guò)此時(shí)的隱式實(shí)例化有一個(gè)情況倘若我們什么也不做是行不通的,就比如下面的實(shí)例化:
Add(a, d);
? ?此時(shí)如果這么寫的話編譯器是給我們報(bào)錯(cuò)的,編譯器報(bào)錯(cuò)的原因解釋的不太行,這里小編提一嘴,報(bào)錯(cuò)后編譯器給出的錯(cuò)誤并不是完全正確的,有時(shí)候也是會(huì)有出錯(cuò)的情況,這里出錯(cuò)的原因其實(shí)就是此時(shí)的編譯器是無(wú)法理解此時(shí)我們傳的類型到底是什么,如果是按照第一個(gè)參數(shù)來(lái)斷定T的類型,那么在第二個(gè)參數(shù)的時(shí)候便會(huì)出錯(cuò),這讓編譯器摸不著頭腦了,對(duì)于這個(gè)問(wèn)題的解決策略,小編有兩種解法可以幫助我們?nèi)グ堰@個(gè)題目解決,如下所示:
1.把某一個(gè)元素強(qiáng)制類型轉(zhuǎn)換(簡(jiǎn)單粗暴)
Add(a, (int)d);
2. 再寫一個(gè)模版,不過(guò)此時(shí)的模版參數(shù)是兩個(gè),如下所示:
template
T1 Add(T1 x, T2 y)
{
return x + y;
}
? 對(duì)于第一種解決方案,小編認(rèn)為還是蠻簡(jiǎn)單粗暴的,我們僅需隨機(jī)在兩個(gè)實(shí)參中把其中一個(gè)進(jìn)行強(qiáng)制類型轉(zhuǎn)換,從而讓編譯器不在犯迷糊,這是是用一個(gè)模版參量解決的方案之一,等會(huì)再顯示類型轉(zhuǎn)換的時(shí)候小編還會(huì)繼續(xù)說(shuō),對(duì)于第二種方式,從嚴(yán)格意義上來(lái)講,這是牽扯到了另一個(gè)模版了,如果我們?cè)趯戭}目的時(shí)候強(qiáng)制只有一個(gè)模版參量,那么就用第一個(gè)就可以了,反之使用第二個(gè)就好了,這便是隱式實(shí)例化的內(nèi)容,下面開始講解顯示實(shí)例化。
2.4.2.顯示實(shí)例化
? 對(duì)于顯示實(shí)例化,它的用法也是很簡(jiǎn)單,我們僅需在函數(shù)名后加上<>即可,<>里面放置的是我們想要模版參數(shù)類型的實(shí)際類型,還是拿上面的整形和浮點(diǎn)型相加來(lái)進(jìn)行舉例,如果我們僅寫一個(gè)模版參量的模版,那么強(qiáng)制類型轉(zhuǎn)換是第一種解決方案,顯示實(shí)例化則是第二種解決方案,如下所示:
Add
? 上面的代碼就可以成功的去運(yùn)行,因?yàn)榇藭r(shí)我們使用了顯示實(shí)例化,我們直接告訴了編譯器,此時(shí)的模版參量就是int類型,編譯器會(huì)在傳參的過(guò)程中默默會(huì)生成隱式類型轉(zhuǎn)換,把其中不是整形的轉(zhuǎn)換為整形的,這就是顯示類型實(shí)例化,難度也沒(méi)有很大,各位讀者朋友要知道這些實(shí)例化的方法,避免以后框框出錯(cuò),下面我們進(jìn)入函數(shù)模版最后一部分的講解。
2.5.函數(shù)模版的匹配原則
? 肯定有讀書朋友好奇,倘若我在寫Add函數(shù)的時(shí)候,我寫了一份整形類型的Add函數(shù),寫了一份單參量的函數(shù)模版,還寫了一份雙模版的函數(shù)模版,那么如果我調(diào)用Add(1,2),那么編譯器會(huì)先去調(diào)用哪一份函數(shù)呢?不要著急,下面小編就介紹一下函數(shù)模版的匹配原則:
?1.一個(gè)非模版函數(shù)可以和一個(gè)同名的函數(shù)模版同時(shí)存在,而且該函數(shù)模版還可以被實(shí)例化為這個(gè)非模版函數(shù)。這個(gè)說(shuō)法是很容易讓人去理解的,它意味著我們寫完了一個(gè)模版Add以后,還可以寫一個(gè)專屬整型的Add函數(shù),這倆是可以同時(shí)存在的,當(dāng)這兩個(gè)同時(shí)存在時(shí),倘若我寫了一個(gè)Add(1,2),編譯器是會(huì)去調(diào)用整型的Add函數(shù),而不會(huì)去使用模版,對(duì)于這個(gè)特點(diǎn)小編會(huì)在下面說(shuō)的,這里我提前說(shuō)一下,我們可以把模版想成菜單,把專屬整型的Add函數(shù)認(rèn)定為預(yù)制菜,編譯器也不傻,有預(yù)制菜不用去用菜單自己炒一個(gè),所以會(huì)去調(diào)用后面的函數(shù),如下圖所示:
int Add(int x, int y)
{
return x = y;
}
template
T Add(T x, T y)
{
return x + y;
}
int main()
{
int a = 12, b = 13;
Add(a, b);
}
? 上圖就顯示了編譯器是會(huì)調(diào)用現(xiàn)成的函數(shù)的,這就引出了第二個(gè)特點(diǎn):
?2.對(duì)于非模版函數(shù)和同名函數(shù)模版,如果其他條件都相同,在調(diào)用時(shí)會(huì)優(yōu)先調(diào)用非模版函數(shù)而不會(huì)從該模版產(chǎn)生出一個(gè)實(shí)例,如果模版可以產(chǎn)生一個(gè)具有更好匹配的函數(shù),那么還是會(huì)選擇模版。這個(gè)特點(diǎn)小編也在前面說(shuō)了,編譯器又不是傻子,它雖然是一個(gè)牛馬,但它知道如何做才會(huì)省事,所以它是會(huì)篩選模版函數(shù)的,就比如我寫了兩個(gè)模版參量的模版和一個(gè)模版參量的模版,如果我用了Add(1,2),那么是會(huì)去調(diào)用一個(gè)參量的,因?yàn)槭∈?,但是如果我是Add(1,1.1),那么系統(tǒng)會(huì)直接調(diào)用兩個(gè)模版參量的,如下所示:
template
T Add(T x, T y)
{
return x + y;
}
template
T1 Add(T1 x, T2 y)
{
return x + y;
}
int main()
{
int a = 12, b = 13;
double c = 11.1, d = 12.2;
Add(a, b);
Add(a, d);
}
? 上面的調(diào)試過(guò)程便給我們展示了函數(shù)模版是如何去進(jìn)行調(diào)用的,如果都是一個(gè)類型,編譯器是會(huì)調(diào)用單模版參量的模版,因?yàn)槭∈?,僅需把一個(gè)T轉(zhuǎn)換為一個(gè)類型即可;如果有兩個(gè)類型,那么自然的就會(huì)去調(diào)用兩個(gè)模版參量的模版,這就是第二個(gè)匹配原則,下面來(lái)看第三個(gè):
?3.函數(shù)模擬不允許自動(dòng)類型轉(zhuǎn)換,但是普通函數(shù)可以進(jìn)行自動(dòng)類型轉(zhuǎn)換。這個(gè)特點(diǎn)小編在上面也就展示出來(lái)了,這里就不多說(shuō)明了,這就是函數(shù)模版的寫法,下面我們繼續(xù)出發(fā),開始講述類模版的寫法~
3.類模版
3.1.類模版的定義格式
? 其實(shí)函數(shù)模版就已經(jīng)講述了許多模版的特性了,所以在類模版的時(shí)候小編會(huì)少說(shuō)一點(diǎn)知識(shí)點(diǎn),不然就顯的我水字?jǐn)?shù)了,下面小編就通過(guò)寫代碼的方式來(lái)幫助讀者朋友知道類模版的定義格式:
template
class wang
{
//類內(nèi)成員函數(shù)的定義或者類內(nèi)成員的定義
};
? 上面就是類模版的定義格式,下面小編就以Stack類模版來(lái)幫助各位更好的去理解類模版:
template
class Stack
{
public:
Stack(int capcaity = 4)
{
_arr = new Stack[capcaity];
_size = 0;
_capcaity = capcaity;
}
private:
T* _arr;
int _capcaity;
int _size;
};
? ?上面就是小編簡(jiǎn)單寫出來(lái)的Stack類模版,其實(shí)類模版和函數(shù)模版是很像的,只不過(guò)一個(gè)是函數(shù)一個(gè)類罷了,想必現(xiàn)在很多讀者朋友會(huì)好奇類模版如何實(shí)例化,不要著急,下面小編就給各位讀者朋友講述一下類模版的實(shí)例化。
3.2.類模版的實(shí)例化
? 類模版的實(shí)例化和函數(shù)模版的實(shí)例化不同,類模版的實(shí)例化需要在類模版后面加上<>,然后將實(shí)例化對(duì)象的類型放在<>即可,簡(jiǎn)單來(lái)說(shuō)類模版只可以顯示實(shí)例化,因?yàn)槿绻贿@樣干的話編譯器不知道如何去進(jìn)行實(shí)例化,類模版的名字并不是真正的類,而實(shí)例化的結(jié)果才是真正的類,下面小編就給出類模版實(shí)例化的代碼:
int main()
{
Stack
Stack s2; //這樣實(shí)例化會(huì)報(bào)錯(cuò),報(bào)錯(cuò)原因:缺少 類模板 "Stack" 的參數(shù)列表
}
? 對(duì)于類模版的實(shí)例化,就必須顯示實(shí)例化,這個(gè)點(diǎn)各位讀者朋友一定要記住,以上就是類模版的講解,講解的還是蠻少的,因?yàn)楹瘮?shù)模版其實(shí)就把模版的一些特性講述的很多了,類模版的講述僅僅就是幫助讀者朋友去了解類模版的使用罷了。
4.總結(jié)
? 以上就是本篇博客小編所要講述的內(nèi)容,模版是C++比較重要的內(nèi)容,也是一個(gè)為后面知識(shí)學(xué)習(xí)打下的基礎(chǔ),小編之后就要開始講解STL庫(kù)了,到時(shí)候?qū)?huì)給讀者朋友們展示一下C++內(nèi)容最爽的部分,如果本篇文章出現(xiàn)錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論區(qū)指出,小編定會(huì)及時(shí)回復(fù),那么,大佬們,我們下一篇文章見(jiàn)啦?。ㄑ捞壅嬉?/p>
柚子快報(bào)邀請(qǐng)碼778899分享:c語(yǔ)言 探索C嘎嘎:模版初階
精彩文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。