本文轉載自【微信公眾號:羽林君,ID:Conscience_Remains】經微信公眾號授權轉載,如需轉載與原文作者聯繫
1. 模板是泛型編程的基礎,泛型編程即以一種獨立於任何特定類型的方式編寫代碼。C++模板的作用,類似於C中的typedef,不過C++中模板有更多的靈活性。C++模板類型,類似於Objective-C中的泛型。C++通過類模板來實現泛型支持。
2.C++中有兩種模板,分別是函數模板和類模板。
一、類模板
當程序有出現有一些相似的類,這個時候我們可以選擇使用類模板進行定義,但是與函數模板不同,類模板不能推斷實例化(下面有描述推斷的情況),所以你只能顯示執行類型參數使用Printer<int> p(1),而不能讓編譯器自行推斷Printer p(1)。
示例代碼部分
template<typename T> 標誌:
T T 可以替換為我們需要的變量類型:例如 int double等
template<typename T>
class AAA{
private:
T t;
public:
void test_func(const T &t);
void print(void);
};
template<typename T>
void AAA<T>::test_func(const T&t)
{
this->t = t;
}
template<typename T>
void AAA<T>::print(void)
{
cout<<t<<endl;
}
使用介紹
1:用時再實例化
AAA<int>a;
AAA<double>b;
2:事先實例化
/*事先實例化*/
template AAA<int>
/*再使用*/
AAA<int >a;
類的定做與繼承
函數模板可以重載,類模板也可以進行重載,這樣的類叫做定做。
定義好<>裡面的類型之後,類裡面所有的成員都可以修改,而派生類可以與之前不一樣。
在模板類的繼承中,需要注意以下三點:如果父類自定義了構造函數,記得子類要使用構造函數列表來初始化繼承的時候,如果子類不是模板類,則必須指明當前的父類的類型,因為要分配內存空間 繼承的時候,如果子類是模板類,要麼指定父類的類型,要麼用子類的泛型來指定父類
template<>
class AAA<int>{
public:
void test_func_int(const int &t)
{
cout<<t<<endl;
}
void print(void);
};
void AAA<int>::print(void)
{
cout<<"for test"<<endl;
}
二、函數模板
函數模板:函數重載實現相同函數名的實現,但是如果有很多種實現類型框架需要實現,我們便不可以重複的寫如此多的重載函數,我們需要函數模板去實現,在重載函數使用不同的參數類型作為一個參數定義一個函數,這便是函數模板的初始定義。
函數模板實例化
函數模板只是一套編譯指令,一般寫在頭文件.編譯程序的時候,編譯器根據函數的參數來推導生成 模板的函數,類似Makefile規則.
通過模板得到函數的過程,我們稱之為模板的實例化或者叫模板的具體化.
示例代碼
using namespace std;
template<typename T>
const T& mymax(const T& a,const T& b)
{
// cout<<"mymax(T& a,T& b)"<<endl;
cout<<__PRETTY_FUNCTION__<<endl;
return (a<b)?b:a;
}
template<typename T>
const T * mymax1(const T* a,const T* b)
{
// cout<<"mymax(T& a,T& b)"<<endl;
cout<<__PRETTY_FUNCTION__<<endl;
return (a<b)?b:a;
}
template<typename T>
void test_func(T f)
{
cout<<__PRETTY_FUNCTION__<<endl;
}
int f1(int a,int b)
{
return 0;
}
void add(int a,int b)
{
cout<<"add(int a,int b) ="<<(a+b)<<endl;/*普通函數可以進行簡單的隱式類型轉化*/
}
int main(int argc,char** argv)
{
int a = 1,b = 2.1;
add(a,b);/*隱式轉化,但是函數模板不支持此種轉化*/
int ia = 1, ib = 2;
mymax(ia,ib);/*隱式轉化支持從可讀寫轉為只讀 ,從高到低*/
char ca[] = "ab";
char cb[] = "cd";
mymax(ca,cb);
mymax1(ca,cb);/*s數組轉化為指針*/
char ca1[] = "abc";/*長度不一致的時候 error*/
char cb1[] = "cd";
// mymax(ca1,cb1);/*無法推導出同樣的T char&[3],char&[2]*/
mymax1(ca1,cb1);/*s數組轉化為指針*/
test_func(f1);
test_func(&f1);
return 0;
}
在匹配函數之後,發現有出現匹配度相同的函數,優先選擇普通函數。對於多個模板函數,選擇「更特化」函數,否則出現二義性錯誤。
函數模板使用的時候注意調用使用的順序規則。最特化:更特殊、更具體、更細化。