C++基础:模板,函数模板和类模板
文章目錄
- 1. 函數(shù)模板
- 2. 類模板
- 3. 模板特化
- 3.1 函數(shù)模板特化
- 3.2 類模板特化
- 4. 非類型模板參數(shù)
模板是允許函數(shù)或類通過泛性的形式表現(xiàn)或運(yùn)行的特性
1. 函數(shù)模板
模板可以使函數(shù)或者類只寫一份代碼而對(duì)應(yīng)不同的類型
取整數(shù)、小數(shù)、字符中的最大值
#include <iostream> using namespace std;/* int Max(int a,int b){return a>b?a:b; }double Max(double a,double b){return a>b?a:b; }double Max(char a,char b){return a>b?a:b; } */template<typename T> // 起一個(gè)模板類型名 T Max(T a,T b){return a>b?a:b; }int main(){cout << Max(10,12) << endl; // int Max(int a,int b)cout << Max(1.0,1.2) << endl; // double Max(double a,double b)cout << Max('a','c') << endl; // char Max(char a,char b) }結(jié)果為:
12 1.2 c兩個(gè)對(duì)象交換順序
#include <iostream> #include <sstream> using namespace std; /* void Swap(int& a,int& b){int t = a;a = b;b = t; } */// 兩個(gè)對(duì)象交換 template <typename T> void Swap(T& a,T& b){T t = a;a = b;b = t; }int main(){{int a = 10;int b = 20;cout << a << "," << b << endl;Swap(a,b); // void Swap(int,int)cout << a << "," << b << endl;}{float a = 12.3;float b = 32.1;cout << a << "," << b << endl;Swap(a,b); // void Swap(double,double)cout << a << "," << b << endl;} }結(jié)果為:
10,20 20,10 12.3,32.1 32.1,12.3把某個(gè)類型轉(zhuǎn)化為字符串
#include <iostream> #include <sstream> using namespace std;//把某個(gè)類型轉(zhuǎn)換為字符串 template <typename T> string NumberToString(T n){ostringstream oss;oss << n;return oss.str(); }int main(){cout << NumberToString(10) << endl;cout << NumberToString(1.3) << endl; }結(jié)果為:
10 1.3對(duì)于不知道返回值類型的情況,我們需要用<尖括弧>設(shè)定類型
字符串轉(zhuǎn)換為某個(gè)類型
結(jié)果為:
20 1.25對(duì)于傳入兩個(gè)數(shù)類型不一致,也可以做相應(yīng)設(shè)定
#include <iostream> using namespace std;template<typename T> T Max(T a,T b){return a>b?a:b; }int main(){cout << Max((double)10,12.2) << endl; // 兩個(gè)數(shù)類型不匹配 cout << Max<double>(10,12.2) << endl; }結(jié)果為:
12.2 12.2該程序不能使用小寫max,會(huì)出現(xiàn)函數(shù)名沖突的情況
要想使用小寫max,需要添加命名空間
2. 類模板
與函數(shù)模板不同,類模板必須定義參數(shù)類型
求圓的周長和面積
結(jié)果為:
12.5664,12.5664 13.823,15.2053逐個(gè)創(chuàng)建數(shù)組并打印
#include <iostream> using namespace std;template <typename T> // 模板 class SeqList{T* header;size_t count; public:SeqList():header(NULL),count(0){} // 構(gòu)造函數(shù)// ~SeqList(){} 析構(gòu)函數(shù)void Append(T val){ // 添加元素T* temp = new T[count+1]; // 申請(qǐng)一塊兒新的連續(xù)的空間for(int i=0;i<count;++i){ // 把原來的部分復(fù)制進(jìn)來temp[i] = header[i];}temp[count] = val; // 把新加的數(shù)放到后面 ++count; // 數(shù)據(jù)個(gè)數(shù)加一delete [] header; // 把之前的空間釋放掉header = temp; // 頭指針指向新的順序表}size_t GetSize() const{return count;} // 數(shù)據(jù)長度T Get(int i) {return header[i];} // 某個(gè)元素的值T& operator[](int i){return header[i];} // []運(yùn)算符重載 };int main(){{SeqList<int> arr; // 使用模板類,需要加類型arr.Append(2);arr.Append(4);arr.Append(3);arr.Append(5);for(int i=0;i<arr.GetSize();++i){ // 逐個(gè)打印cout << arr.Get(i) << " ";}cout << endl;}{SeqList<float> arr; // 使用模板類,需要加類型arr.Append(2.2);arr.Append(4.4);arr.Append(3.3);arr.Append(5.5);for(int i=0;i<arr.GetSize();++i){ // 逐個(gè)打印cout << arr[i] << " "; // 這里使用[]運(yùn)算符重載}cout << endl;} }結(jié)果為:
2 4 3 5 2.2 4.4 3.3 5.53. 模板特化
3.1 函數(shù)模板特化
出現(xiàn)問題:比較字符串大小時(shí)會(huì)出現(xiàn)比較錯(cuò)誤的情況
#include <iostream> #include <sstream> using namespace std;template<typename T> T Max(T a,T b){return a>b?a:b; }int main(){cout << Max("abcd","defg") << endl; }結(jié)果為:
abcd比較錯(cuò)誤的原因是:程序會(huì)按照地址進(jìn)行比較,找出較大的那一個(gè)
解決方法:模板特化
#include <iostream> #include <sstream> #include <cstring> using namespace std;template<typename T> T Max(T a,T b){return a>b?a:b; }// 模板特化 template<> const char* Max(const char* a,const char* b){return strcmp(a,b)>0?a:b; }int main(){cout << Max("abcd","defg") << endl;// cout << Max(string("abcd"),string("defg")) << endl; }結(jié)果為:
defg模板特化的作用:
特殊處理的模板,指定具體的模板類型
3.2 類模板特化
#include <iostream> #include <cmath> using namespace std;// 圓形 template <typename T> class Circle{T r; public:Circle(T r):r(r){}float GetLength() const{return 2*M_PI*r;}float GetArea() const{return M_PI*r*r;} };// 模板特化 template<> class Circle<int>{int r; public:Circle(int r):r(r){}float GetLength() const{cout << "Circle<int>:" ;return 2*M_PI*r;}float GetArea() const{cout << "Circle<int>:" ;return M_PI*r*r;} };int main(){Circle<int> a(2); // 這里使用的就是模板特化的類cout << a.GetLength() << "," << a.GetArea() << endl;Circle<double> b(2.2);cout << b.GetLength() << "," << b.GetArea() << endl; }結(jié)果為:
Circle<int>:12.5664,Circle<int>:12.5664 13.823,15.2053這個(gè)例子屬于全特化
全特化:
偏特化:
4. 非類型模板參數(shù)
#include <iostream> #include <cmath> using namespace std;template<typename T,int n> // 非類型模板參數(shù) void PrintArr(const T (&arr)[n]){ // 只針對(duì)數(shù)組的特殊寫法for(int i=0;i<n;++i){cout << arr[i] << " ";}cout << endl; }int main(){int arr[] = {1,3,5,7}; // int [4]PrintArr(arr); // 可以檢測到數(shù)據(jù)數(shù)量char str[] = "abcd"; // char [5]PrintArr(str);float fs[] = {1.1,2.2,3.3};PrintArr(fs); // PrintArr(const float (&arr)[3]) }結(jié)果為:
1 3 5 7 a b c d 1.1 2.2 3.3優(yōu)化: 函數(shù)模板參數(shù)盡量使用引用類型 const &
例如:
Circle(const T& r):r(r){} const T& Max(const T& a,const T& b){可以避免拷貝構(gòu)造
template <typename T> 也可以寫成 template <class T>
總結(jié)
以上是生活随笔為你收集整理的C++基础:模板,函数模板和类模板的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OSGB压缩算法有哪些?
- 下一篇: 工厂模式C++实现(三种工厂模式附详细注