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