日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++基础:模板,函数模板和类模板

發布時間:2024/3/13 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++基础:模板,函数模板和类模板 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1. 函數模板
  • 2. 類模板
  • 3. 模板特化
    • 3.1 函數模板特化
    • 3.2 類模板特化
  • 4. 非類型模板參數

模板是允許函數或類通過泛性的形式表現或運行的特性

1. 函數模板

模板可以使函數或者類只寫一份代碼而對應不同的類型

取整數、小數、字符中的最大值

#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> // 起一個模板類型名 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) }

結果為:

12 1.2 c

兩個對象交換順序

#include <iostream> #include <sstream> using namespace std; /* void Swap(int& a,int& b){int t = a;a = b;b = t; } */// 兩個對象交換 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;} }

結果為:

10,20 20,10 12.3,32.1 32.1,12.3

把某個類型轉化為字符串

#include <iostream> #include <sstream> using namespace std;//把某個類型轉換為字符串 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; }

結果為:

10 1.3

對于不知道返回值類型的情況,我們需要用<尖括弧>設定類型
字符串轉換為某個類型

#include <iostream> #include <sstream> using namespace std;// 字符串轉換為某個類型 template <typename T> T StringToNumber(const string& s){T res;istringstream iss(s);iss >> res;return res; }int main(){cout << StringToNumber<int>("20") << endl;cout << StringToNumber<float>("1.25") << endl; }

結果為:

20 1.25

對于傳入兩個數類型不一致,也可以做相應設定

#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; // 兩個數類型不匹配 cout << Max<double>(10,12.2) << endl; }

結果為:

12.2 12.2

該程序不能使用小寫max,會出現函數名沖突的情況
要想使用小寫max,需要添加命名空間

#include <iostream> using namespace std;namespace My{ // 添加命名空間template<typename T>T max(T a,T b){return a>b?a:b;} }int main(){cout << My::max((double)10,12.2) << endl;cout << My::max<double>(10,12.2) << endl; }

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;} };int main(){Circle<int> a(2); // 必須定義參數類型cout << a.GetLength() << "," << a.GetArea() << endl;Circle<double> b(2.2);cout << b.GetLength() << "," << b.GetArea() << endl; }

結果為:

12.5664,12.5664 13.823,15.2053

逐個創建數組并打印

#include <iostream> using namespace std;template <typename T> // 模板 class SeqList{T* header;size_t count; public:SeqList():header(NULL),count(0){} // 構造函數// ~SeqList(){} 析構函數void Append(T val){ // 添加元素T* temp = new T[count+1]; // 申請一塊兒新的連續的空間for(int i=0;i<count;++i){ // 把原來的部分復制進來temp[i] = header[i];}temp[count] = val; // 把新加的數放到后面 ++count; // 數據個數加一delete [] header; // 把之前的空間釋放掉header = temp; // 頭指針指向新的順序表}size_t GetSize() const{return count;} // 數據長度T Get(int i) {return header[i];} // 某個元素的值T& operator[](int i){return header[i];} // []運算符重載 };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){ // 逐個打印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){ // 逐個打印cout << arr[i] << " "; // 這里使用[]運算符重載}cout << endl;} }

結果為:

2 4 3 5 2.2 4.4 3.3 5.5

3. 模板特化

3.1 函數模板特化

出現問題:比較字符串大小時會出現比較錯誤的情況

#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; }

結果為:

abcd

比較錯誤的原因是:程序會按照地址進行比較,找出較大的那一個

解決方法:模板特化

#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; }

結果為:

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; }

結果為:

Circle<int>12.5664,Circle<int>12.5664 13.823,15.2053

這個例子屬于全特化

全特化:

  • 聲明一個模板空參數列表template<>
  • 在類名稱后面的<>中顯示指定類型
  • 偏特化:

  • 在一個模板類參數列表不指定或者指定部分具體類型
  • 在類名稱后面的對應類型中顯示指定該類型
  • template<typename T> class Test<T,int>{};

    4. 非類型模板參數

    #include <iostream> #include <cmath> using namespace std;template<typename T,int n> // 非類型模板參數 void PrintArr(const T (&arr)[n]){ // 只針對數組的特殊寫法for(int i=0;i<n;++i){cout << arr[i] << " ";}cout << endl; }int main(){int arr[] = {1,3,5,7}; // int [4]PrintArr(arr); // 可以檢測到數據數量char str[] = "abcd"; // char [5]PrintArr(str);float fs[] = {1.1,2.2,3.3};PrintArr(fs); // PrintArr(const float (&arr)[3]) }

    結果為:

    1 3 5 7 a b c d 1.1 2.2 3.3

    優化: 函數模板參數盡量使用引用類型 const &

  • 對象內容不改變
  • 對象是在函數外定義的
  • 例如:

    Circle(const T& r):r(r){} const T& Max(const T& a,const T& b){

    可以避免拷貝構造

    template <typename T> 也可以寫成 template <class T>

    總結

    以上是生活随笔為你收集整理的C++基础:模板,函数模板和类模板的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。