網(wǎng)站建設(shè) 事業(yè)單位 安全外貿(mào)網(wǎng)站平臺都有哪些 免費(fèi)的
文章目錄
- 1 泛型編程
- 2 函數(shù)模板
- 2.1 函數(shù)模板概念
- 2.2 函數(shù)模板格式
- 2.3 函數(shù)模板的實(shí)例化
- 2.3.1 隱式實(shí)例化
- 2.3.1.1 定義
- 2.3.1.2 代碼演示
- 2.3.1.3 運(yùn)行結(jié)果
- 2.3.1.4 缺點(diǎn)
- 2.3.2 顯式實(shí)例化
- 2.3.2.1 格式
- 2.3.2.2 代碼演示
- 2.3.2.3 運(yùn)行結(jié)果
- 2.4 模板參數(shù)的匹配原則
- 2.4.1
- 2.4.2
- 2.4.3
- 3 類模板
- 3.1 類模板格式
- 代碼演示
- 3.2 類模板實(shí)例化
1 泛型編程
編寫與類型無關(guān)的通用代碼,是代碼復(fù)用的一種手段。模板是泛型編程的基礎(chǔ)。其中模板包括函數(shù)模板和類模板。
2 函數(shù)模板
2.1 函數(shù)模板概念
函數(shù)模板代表了一個(gè)函數(shù)家族,該函數(shù)模板與類型無關(guān),在使用時(shí)被參數(shù)化,根據(jù)實(shí)參類型產(chǎn)生函數(shù)的特定類型版本。
2.2 函數(shù)模板格式
typename:定義模板參數(shù)關(guān)鍵字,也可使用class
template<typename T1[,typename T2,typename T3]>
返回值類型 函數(shù)名(參數(shù)列表){}
或
template<class T1[,class T2,class T3]>
返回值類型 函數(shù)名(參數(shù)列表){}
2.3 函數(shù)模板的實(shí)例化
用不同類型的參數(shù)使用函數(shù)模板時(shí),稱為函數(shù)模板的實(shí)例化。模板參數(shù)實(shí)例化分為隱式實(shí)例化和顯式實(shí)例化。
2.3.1 隱式實(shí)例化
2.3.1.1 定義
編譯器通過實(shí)參的數(shù)據(jù)類型推演模板參數(shù)的實(shí)際類型
2.3.1.2 代碼演示
// 模板實(shí)現(xiàn)兩數(shù)交換
template<class T>
void Swap(T& a, T& b) {T t = a;a = b;b = t;
}int main() {// 隱式實(shí)例化int a1 = 10, a2 = 20;cout << "a1 = " << a1 << " a2 = " << a2 << endl;// 此時(shí)模板參數(shù)為intSwap(a1, a2);cout << "swap" << endl;cout << "a1 = " << a1 << " a2 = " << a2 << endl;cout<<endl;double a3 = 10.1, a4 = 20.1;cout << "a3 = " << a3 << " a4 = " << a4 << endl;// 此時(shí)模板參數(shù)為doubleSwap(a3, a4);cout << "swap" << endl;cout << "a3 = " << a3 << " a4 = " << a4 << endl;return 0;
}
2.3.1.3 運(yùn)行結(jié)果
2.3.1.4 缺點(diǎn)
當(dāng)兩參數(shù)數(shù)據(jù)類型不一致時(shí),編譯器無法推演出模板的數(shù)據(jù)類型
可通過類型強(qiáng)轉(zhuǎn)或顯式實(shí)例化解決。
類型強(qiáng)轉(zhuǎn):Swap(a1,(int)a3);
2.3.2 顯式實(shí)例化
2.3.2.1 格式
在函數(shù)名后的<>中指定模板參數(shù)的實(shí)際類型
2.3.2.2 代碼演示
// 實(shí)現(xiàn)兩數(shù)相加模板
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main(){int c1 = 10, c2 = 20;double d1 = 10.1, d2 = 20.2;cout << Add(c1, c2) << endl;cout << Add(d1, d2) << endl;// 參數(shù)類型強(qiáng)轉(zhuǎn)cout << Add((double)c1, d2) << endl;// 顯示實(shí)例化// 指定為int型cout << Add<int>(c1, d2) << endl;// 指定為double型cout << Add<double>(c1, d2) << endl;return 0;
}
2.3.2.3 運(yùn)行結(jié)果
經(jīng)過顯式實(shí)例化后int+double型也可以算出和
2.4 模板參數(shù)的匹配原則
2.4.1
一個(gè)非模板函數(shù)可以和一個(gè)同名的函數(shù)模板同時(shí)存在,而且該函數(shù)模板還可以被實(shí)例化為這個(gè)非模板函數(shù)。
2.4.2
對于非模板函數(shù)和同名函數(shù)模板,如果其他條件都相同,在調(diào)動(dòng)時(shí)會(huì)優(yōu)先調(diào)用非模板函數(shù)而不會(huì)從該模板產(chǎn)生出一個(gè)實(shí)例。如果模板可以產(chǎn)生一個(gè)具有更好匹配的函數(shù), 那么將選擇模板。
2.4.3
模板函數(shù)不允許自動(dòng)類型轉(zhuǎn)換,但普通函數(shù)可以進(jìn)行自動(dòng)類型轉(zhuǎn)換。
3 類模板
3.1 類模板格式
template<class T>
class 類模板名
{};
代碼演示
// 類模板Vector
template<class T>
class Vector
{
public:Vector(size_t capacity = 10):_pData(new T[capacity]), _size(0), _capacity(capacity) {}~Vector();void PushBack(const T& data);void PushBack(const T& data);void PopBack();// ...size_t Size() { return _size; }T& operator[](size_t pos){assert(pos < _size);return _pData[pos];}
private:T* _pData;size_t _size;size_t _capacity;
};// 注意:類模板中函數(shù)放在類外進(jìn)行定義時(shí),需要加模板參數(shù)列表
template <class T>
Vector<T>::~Vector()
{if (_pData)delete[] _pData;_size = _capacity = 0;
}
};
3.2 類模板實(shí)例化
類模板實(shí)例化需要在類模板名字后跟<>,然后將實(shí)例化的
類型放在<>中即可,類模板名字不是真正的類,而實(shí)例化的結(jié)果才是真正的類。
// vector<int>:類型名
Vector<int> v1;
Vector<double> v2;