這是關(guān)于一個(gè)普通雙非本科大一學(xué)生的C++的學(xué)習(xí)記錄貼
在此前,我學(xué)了一點(diǎn)點(diǎn)C語言還有簡單的數(shù)據(jù)結(jié)構(gòu),如果有小伙伴想和我一起學(xué)習(xí)的,可以私信我交流分享學(xué)習(xí)資料
那么開啟正題
今天學(xué)習(xí)了關(guān)于模板的知識,下面展開分析
1.泛型編程
首先我們思考一個(gè)問題,如何是實(shí)現(xiàn)一個(gè)通用的交互函數(shù)呢
在C語言中,我們可能要定義實(shí)現(xiàn)幾個(gè)不同名稱的swap函數(shù),像這樣
void swap_int(int x1, int x2)
{...}
void swap_double(double x1, double x2)
{...}
void swap_char(char x1, char x2)
{...}
在C++中我們利用函數(shù)重載,可以方便一點(diǎn),像這樣
void swap(int x1, int x2)
{...}
void swap(double x1, double x2)
{...}
void swap(char x1, char x2)
{...}
但是重載的函數(shù)僅僅是類型不同,代碼復(fù)用率比較低,只要有新類型的出現(xiàn),又得增加函數(shù),很麻煩
于是,引出我們今天的主題:模板
模板就像告訴編譯器一個(gè)模子,讓編譯器根據(jù)類型的不同自己生成函數(shù)
隨著模板的引出,我們又不得不引出這樣的名詞:
泛型編程:編寫與類型無關(guān)的代碼,是代碼復(fù)用的一種手段,模板是泛型編程的基礎(chǔ)
2.函數(shù)模板
2.1函數(shù)模板概念
函數(shù)模板代表了一個(gè)函數(shù)家族,該函數(shù)模板與類型無關(guān),在使用時(shí)被參數(shù)化,根據(jù)實(shí)參類型產(chǎn)生函數(shù)的特定類型版本
2.2函數(shù)模板格式
template<typename T1,typename T2...>
返回類型 函數(shù)名(參數(shù)列表){}
(typename是用來定于模板參數(shù)的關(guān)鍵字,也可以用class替代,不能用struct)
下面寫一個(gè)交換函數(shù)模板
template<class T>
void Swap(T& x1, T& x2)
{
T x = x1;
x1 = x2;
x2 = x;
}
2.3函數(shù)模板的原理
函數(shù)模板是一個(gè)藍(lán)圖,它本身不是函數(shù),是編譯器用使用方式產(chǎn)生特定具體類型函數(shù)的模具,所以模板就是將本應(yīng)該我們做的重復(fù)的事情交給了編譯器
在編譯器編譯階段,對于模板函數(shù)的使用,編譯器需要根據(jù)傳入的實(shí)參類型來推演生成對應(yīng)類型的函數(shù)以供調(diào)用,比如當(dāng)double類型使用函數(shù)模板的時(shí)候,編譯器通過對實(shí)參類型的推演,將T確定為double類型,然后產(chǎn)生一份專門處理double類型的代碼,對于其他類型也是這樣
2.4函數(shù)模板的實(shí)例化
用不同類型的參數(shù)使用函數(shù)模板時(shí),稱為函數(shù)模板的實(shí)例化,函數(shù)模板的實(shí)例化分為隱式實(shí)例化和顯式實(shí)例化
1.隱式實(shí)例化
template<class T>
void Swap(T& x1, T& x2)
{
T x = x1;
x1 = x2;
x2 = x;
}
int main()
{
int a = 0;
int b = 1;
Swap(a, b);
return 0;
}
這樣就是隱式實(shí)例化,編譯器會自動識別類型生成函數(shù)并調(diào)用,當(dāng)然如果b是double類型,我們可以在前面加上(int)強(qiáng)轉(zhuǎn)
2.顯式實(shí)例化
template<class T>
void Swap(T& x1, T& x2)
{
T x = x1;
x1 = x2;
x2 = x;
}
int main()
{
int a = 0;
int b = 1;
Swap<int>(a, b);
return 0;
}
像這樣,在函數(shù)名后面的<>中指定模板參數(shù)的實(shí)際類型叫做顯式實(shí)例化
如果類型不匹配,編譯器會嘗試進(jìn)行隱式類型轉(zhuǎn)換,如果無法轉(zhuǎn)換成功編譯器就會報(bào)錯(cuò)
2.5模板參數(shù)匹配原則
1.一個(gè)非模板函數(shù)可以和一個(gè)同名的函數(shù)模板同時(shí)存在,而且該函數(shù)模板還可以被實(shí)例化為這個(gè)非模板函數(shù)
2.對于非模板函數(shù)和同名函數(shù)模板,如果其他條件都相同,在調(diào)動時(shí)會優(yōu)先調(diào)用非模板函數(shù)而不會從該模 板產(chǎn)生出一個(gè)實(shí)例。如果模板可以產(chǎn)生一個(gè)具有更好匹配的函數(shù), 那么將選擇模板
3.模板不允許自動類型轉(zhuǎn)化,但普通函數(shù)可以進(jìn)行自動類型轉(zhuǎn)換
template<class T>
T Add(T x, T y)
{
return x + y;
}
int Add(int x, int y)
{
return x + y;
}
int main()
{
Add(0, 1); // call int Add(int x, int y)
Add<int>(0, 1); // call T Add(T x, T y)
return 0;
}
3.類模板
3.1類模板的定義格式
template<class T1,class T2...>
class? 類模板名
{
//類內(nèi)成員定義
};
下面定義一個(gè)順序表作為演示
template<class T>
class Vector
{
public:
Vector()
:_a(nullptr)
,_size(0)
,_capacity(0)
{}
~Vector();
private:
T* _a;
size_t _size;
size_t _capacity;
};
template<class T> //注意在類外面類函數(shù)時(shí),需要加上模板參數(shù)列表
Vector<T>::~Vector()
{
if (_a)
free(_a);
_size = _capacity = 0;
}
要注意的是,這里的Vector不是具體的類,而是模具
3.2類模板的實(shí)例化
類模板實(shí)例化與函數(shù)模板實(shí)例化不同,類模板實(shí)例化需要在模板名字后跟上<>,然后將實(shí)例化的類型放在<>中即可,類模板名字不是真正的類,而實(shí)例化的結(jié)果才是真正的類
Vector<int> v1;
Vector<double> v2;
//Vector類名 Vector<int>才是類型
總結(jié):模板幫我們解決了一些不必要的重復(fù)代碼,使后面的使用更加便捷,明天開始學(xué)SLT,模板也是對SLT的一個(gè)鋪墊
今天的博客就到這里了,后續(xù)內(nèi)容明天分享,最近因?yàn)榭荚囍茉虿荒芨绿鄡?nèi)容,等考試周結(jié)束了再"快馬加鞭"文章來源:http://www.zghlxwxcb.cn/news/detail-813296.html
新手第一次寫博客,有不對的位置希望大佬們能夠指出,也謝謝大家能看到這里,讓我們一起學(xué)習(xí)進(jìn)步吧?。?!文章來源地址http://www.zghlxwxcb.cn/news/detail-813296.html
到了這里,關(guān)于C++從零開始的打怪升級之路(day12)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!