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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

泛函编程—模板函数_类模板

發布時間:2025/6/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 泛函编程—模板函数_类模板 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數業務邏輯一樣,只是函數參數類型不同
函數模板的本質:類型參數化——泛型編程

語法:

template <typename T> template <class T1,class T2>多個參數類型 類型 函數名(形式參數表) {語句序列; }

函數模板基礎:

template是告訴C++編譯器,開始泛型編程,看到T,不要隨便報錯

template <typename T>//一個模板 void myswap(T& a, T& b) {T c;c = a;a = b; } //調用時,顯式說明類型myswap<int>(x,y);myswap<char>(x,y); //自動類型推倒,盡量不要用myswap(x,y);template <typename T1, typename T2>//兩個模板,定義了一定要用 void myswap(T1& a, T2& b) {}

在使用模板時,遇到修改模板里面內容,需要清除原有方案,重新編譯。

函數模板遇上函數重載:

//函數模板不允許自動類型轉化,嚴格的類型匹配
//普通函數能夠進行自動類型轉化,在不失精度的前提下
1、函數模板可以像普通函數一樣被重載
2、C++編譯器優先考慮普通函數
3、如果函數模板可以產生一個更好的匹配,那么選擇模板(比如在使用普通函數導致精度缺失的時候)
4、可以通過空模板實參列表的語法限定編譯器只通過模板匹配

template <typename T>//一個模板 void myswap(T& a, T& b) {T c;c = a;a = b; } //一個普通函數 void myswap(int& a, char& b) {int c;c = a;a = b; } int a = 10; char c = 'c'; myswap(a,c) //調用普通函數 myswap(c,a) //調用普通函數,進行隱形類型轉換 myswap(a,a) //調用模板函數,嚴格的類型匹配,不會進行類型轉換;但是普通函數如果也有兩個int形參時,優先普通函數,看下一個例子

//模板函數重載 int max(int a, int b) {return a>b?a:b; }
template
<typename T> T max(T a, T b) {return a>b?a:b; }
template
<typename T> T max(T a, T b, T c) {return max(max(a,b), c); }int a = 1; int b = 2; max(a,b); //函數模板和普通函數都滿足調用時,優先普通函數 max<>(a,b);//顯示使用函數模板方法,則使用<>空的類型參數化列表 max(3.0,4.0);//類型一致,可以使用模板。且使用普通函數,失真,則調用函數模板 max(3.0,4.0,5.0);//函數模板可以重載 max('a',100); //類型不一致,不能用函數模板,調用普通函數進行隱式類型轉換

函數模板機制結論:

編譯器并不是把函數模板處理成能夠處理任意類的函數
函數模板通過具體類型產生不同的函數
編譯器會對函數模板進行二次編譯:
聲明的地方對模板代碼本身進行編譯,在調用的地方對參數替換后的代碼進行編譯

?

類模板:
解決問題:多個類功能一致,數據類型不同。
類模板用于實現類所需數據的類型參數化
類模板在表示數組、表、圖等數據結構顯得特別重要;
實現 數據結構 與 算法的分離,類模板可以使 鏈表類型存不同數據類型數據
類模板的定義和使用:

template <typename T> class A { public:A(T a=0){this->a = a;} public:void printA(){cout << "a: " << a << endl;} protected:T a; }
int main() {A<int> a1(10); //模板類是抽象的,需要進行類型具體化a1.printA();system("pause");return 0; }

類模板做函數參數:

void useA(A<int>& b) //C++編譯器要求具體的參數類 {b.printA(); }useA(a1);

繼承中的類模板:

一、模板類派生普通類
子模板類派生時,需要具體化模板類,C++編譯器需要知道父類的數據類型具體是什么
要知道父類所占內存大小,只有數據類型固定才知道如何分配內存

class B:public A<int> { public:B(int a=10, int b=20):A<int>(a) //使用初始化參數列表,初始化父類對象注意父類為模板類時,使用A<int>類類型具體化{this->b = b;} protected: private:int b; }

B b1(
1,2);

二、模板類派生模板類

template <typename T> class C:public A<T> //基類為模板類型 { public:C(T c, T a):A<T>(a) //基類為模板類型{this->c = c;} void printC() {cout << "c1: " << c << endl; } private:T c; }
void main() { C<int>c1(1,2); c1.printC(); system("pause"); }

模板類的函數重載:

友元函數只用于重載 輸入輸出流 << 和 >>
其余使用成員函數,成員函數需要在類中聲明,而<<需要在ostream類中聲明,但我們在C++源碼中修改很麻煩,
所以,使用友元實現。友元函數只需要在需要使用的地方的類中定義ostream為該類的友元函數就可以了。

在模板類中寫友元函數和成員函數重載的方法:
1、所有函數聲明實現都寫在.h文件的內部就可以啦(簡單)
2、聲明和實現分開,但都在一個.cpp內
函數提出來的時候,參數類型、類作用域、返回值注意使用<T>
友元函數:只用于輸入輸出流

類內聲明:friend ostream& operator<< <T> (ostream& out, Complex &c3); //友元函數聲明有<T> 類外實現:template<typename T> ostream& operator<<(ostream& out, Complex<T>& c3) //友元函數是全局函數,不需要類的作用域 {}

template<typename T>
成員函數:

類內聲明: Complex operator+(Complex &c2); //正常寫就可以啦 類外定義:主要三要素 Complex<T> Complex<T>::operator+(Complex<T>& c2) {Complex tem(a+c2.a,b+c2.b);return tem; }

除了輸入輸出流使用友元函數重載,其余最好使用成員函數重載,不然處理起來很麻煩。。。

3、.h和.hpp分開,其他類使用,要包含.hpp(不是.cpp)
這個時候和情況2差不多,濫用友元函數容易出問題。

模板類中的static關鍵字,不同的調用類型,static關鍵字屬于不同的類,這是由模板的實現機制決定的。

static是屬于具體類的。

?

轉載于:https://www.cnblogs.com/Lunais/p/5852367.html

總結

以上是生活随笔為你收集整理的泛函编程—模板函数_类模板的全部內容,希望文章能夠幫你解決所遇到的問題。

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