??博主CSDN主頁:杭電碼農(nóng)-NEO??
?
?專欄分類:C++從入門到精通?
?
??代碼倉庫:NEO的學(xué)習(xí)日記??
?
??關(guān)注我??帶你學(xué)習(xí)C++
? ????
1. 前言
在學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)時會遇見以下的情況
數(shù)據(jù)結(jié)構(gòu)中存儲的類型往往不能確定
所以在實現(xiàn)數(shù)據(jù)結(jié)構(gòu)時往往是這樣做的
typedef int DateType
在寫代碼時用DateType來表示類型
如果想存儲浮點型只需將int改為float
但是這樣寫會遇見一個問題:
寫好數(shù)據(jù)結(jié)構(gòu)類后在創(chuàng)建對象時
此.cpp文件只能創(chuàng)建一種類型的對象
對象存儲的全是int/char/double類型不能同時創(chuàng)建存儲int的和char的對象
Data d1;//存儲的int類型
Date d2;//存儲的char類型
泛型編程:
編寫與類型無關(guān)的通用代碼
是代碼復(fù)用的一種手段
模板是泛型編程的基礎(chǔ)
本章重點:
本篇文章重點講解函數(shù)模板
和類模板的使用以及特性
2. 函數(shù)模板
請看以下函數(shù)代碼:
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
void Swap(double& left, double& right)
{
double temp = left;
left = right;
right = temp;
}
void Swap(char& left, char& right)
{
char temp = left;
left = right;
right = temp;
}
這樣寫非常的麻煩
使用模板可以使代碼通用于不同類型:
swap函數(shù)模板:
template<typename T>
void Swap( T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
寫好上面的代碼后,傳int類型進去
T就會被實例化為int,以此類推
template和typename是規(guī)定
好了必須這樣寫,T是自己取的名字
其中,typename可以用class替換
并且一次性可以定義多個類型:
template<class T1,typename T2,class T3>
3. 函數(shù)模板原理
函數(shù)模板是一個藍圖,它本身并不是函數(shù),是編譯器用使用方式產(chǎn)生特定具體類型函數(shù)的模具。所以其實模板就是將本來應(yīng)該我們做的重復(fù)的事情交給了編譯器
在編譯器編譯階段,對于模板函數(shù)的使用,編譯器需要根據(jù)傳入的實參類型來推演生成對應(yīng)類型的函數(shù)以供調(diào)用。比如:當(dāng)用double類型使用函數(shù)模板時,編譯器通過對實參類型的推演,將T確定為double類型,然后產(chǎn)生一份專門處理double類型的代碼,對于字符類型也是如此
可以用下面這張圖來理解:
4. 函數(shù)模板實例化
隱式實例化
讓編譯器根據(jù)實參推演模板參數(shù)實際類型
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);
Add(d1, d2);
}
第一次調(diào)用的T被推演為int類型
第二粗調(diào)用的T被推演為double
不能這樣寫代碼:
Add(a1, d1);
系統(tǒng)根據(jù)a1推演出T是int類型
但是d1是double類型不能用int
類型的參數(shù)啦接受,所以會報錯
顯示實例化
在函數(shù)名后的<>中指定模板參數(shù)的類型
int main(void)
{
int a = 10;
double b = 20.0;
// 顯式實例化
Add<int>(a, b);
return 0;
}
如果類型不匹配
編譯器會嘗試進行隱式類型轉(zhuǎn)換
若無法轉(zhuǎn)換成功編譯器將會報錯
5. 函數(shù)模板參數(shù)的匹配規(guī)則
模板函數(shù)和普通函數(shù)可以同時存在:
// 專門處理int的加法函數(shù)
int Add(int left, int right)
{
return left + right;
}
// 通用加法函數(shù)
template<class T>
T Add(T left, T right)
{
return left + right;
}
在調(diào)用函數(shù)時若參數(shù)和非模板函數(shù)匹配
那么編譯器會優(yōu)先調(diào)用非模板函數(shù)
若非模板函數(shù)不匹配或模板函數(shù)更匹配
那么編譯器會優(yōu)先調(diào)用模板函數(shù)
Add(10,20)//調(diào)用非模板
Add(11.1,6.3);//調(diào)用模板
6. 類模板
類模板的應(yīng)用非常廣泛
像開頭提到的數(shù)據(jù)結(jié)構(gòu)問題
類模板的定義格式:
template<class T1, class T2, ..., class Tn>
class example
{
// 類內(nèi)成員定義
};
和函數(shù)模板類似,類模板也可以同時
定義多個模板參數(shù)
寫一個簡易的順序表:
template<class T>
class Vector
{
public :
Vector(size_t capacity = 10)
: _Data(new T[capacity])
, _size(0)
, _capacity(capacity)
{}
T& operator[](size_t pos)
{
assert(pos < _size);
return _Data[pos];
}
private:
T* _Data;
size_t _size;
size_t _capacity;
};
所有實際類型需要出現(xiàn)的地方用T代替
7. 類模板的實例化
和函數(shù)模板不同,類模板沒有隱式推演用戶必須顯示實例化
Vector<int> v1;
注意:
Vector是類名
Vector< int >才是類型
當(dāng)在類中聲明一個函數(shù)
但是想在類外定義時
若函數(shù)的參數(shù)或內(nèi)部使用的類型
和模板有關(guān)系,那么必須這樣寫:
template<class T>
class Vector
{
public :
//類中聲明函數(shù)
void push_back(T x);
private:
T* _Data;
size_t _size;
size_t _capacity;
};
類外定義:
template<class T>
void Vector<T>::push_back(T x)
{
_Date[_size] = x;
_size++;
}
注:必須要再加上類模板template
并且要指定類域
8. 總結(jié)以及拓展
泛型編程是C++的一大利器
它極大的減少了代碼的復(fù)雜程度
并且增加了代碼的可讀性
C++基礎(chǔ)部分的內(nèi)容已經(jīng)全部結(jié)束
下一階段進入C++中階:STL的使用
拓展:文章來源:http://www.zghlxwxcb.cn/news/detail-642530.html
泛型編程拓展閱讀文章來源地址http://www.zghlxwxcb.cn/news/detail-642530.html
到了這里,關(guān)于【C++基礎(chǔ)(十)】C++泛型編程--模板初階的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!