1,一個類模板至少具備一個類參數,類參數是個符號以表示將要被某個肯定數據類型代替的類型。ios
1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 template <class T> 7 class Array { 8 public: 9 T& operator [](int); 10 const T& operator [](int); 11 Array(int); 12 ~Array(); 13 int get_size() const { return size;} 14 private: 15 char* a; 16 int size; 17 Array(); // 實例化的時候必須給出大小 18 T dummy_val; 19 }; 20 21 template<class T> 22 T& Array<T>::operator [](int i) { 23 if(i < 0 || i >= size) { 24 cerr << "index "<<i<<" out of bounds! "; 25 return dummy_val; 26 } 27 return a[i]; 28 } 29 30 template<class T> 31 T& Array<T>::operator [](int i) const { 32 if(i < 0 || i >= size) { 33 cerr << "index "<<i<<" out of bounds! "; 34 return dummy_val; 35 } 36 return a[i]; 37 } 38 39 template<class T> 40 Array<T>::Array(int s) { 41 a = new T[size = s]; 42 } 43 44 template<class T> 45 Array<T>::~Array() { 46 delete[] a; 47 } 48 49 template<class T> 50 ostream operator<<(ostream& os,const Array<T>& arr) { // 頂層函數重載 51 for(int i=0;i<arr.get_size();++i) 52 os<<arr[i]<<endl; 53 return os; 54 }
因爲 Array 類的參數化構造函數與重載的下標操做符在類聲明以外定義,所以須要在定義以前加上模板頭:template <class T>。程序員
因爲 Array 是個模板類,所以類名是 Array<T>,這裏 T 是模板頭的類參數。ide
2,類模板能夠擁有多個類參數,這些參數用逗號隔開。每一個類參數前都必須有關鍵字 class 或 typename。函數
1 template<class T1,class T2,class T3> 2 class Sample { 3 public: 4 T2 m(T3 p) { } // expects a T3 arg,returns a T2 5 private: 6 T1 x; // var of type T1 7 };
3,模板實例:咱們經過 < > 中指定數據類型來使用一個模板類。this
1 int main() { 2 Array<int> a1(10); // Array of 10 int 3 4 return 0; 5 }
以上語法表面用 int 來替換模板類 Array 聲明的類參數 T,編譯器會將在 Array 聲明中全部的類參數 T 替換成 int。spa
用內建的或自定義的數據類型均可以建立模板實例code
1 class Task { // user-defined data type 2 //... 3 }; 4 5 Array<Task> tasks(10);
4,一個對象不能屬於像 Array 或 Array<T> 的對象,但咱們能夠定義類型爲 Array<int> 的對象。對象
5,參數表中的類模板:類模板能夠做爲一種數據類型出如今參數表中。blog
1 template<class T> 2 ostream operator<<(ostream& os,const Array<T>& arr) { // 頂層函數重載 3 for(int i=0;i<arr.get_size();++i) 4 os<<arr[i]<<endl; 5 return os; 6 }
6,模板的函數式參數:類模板必須至少有一個類參數,固然能夠有多個類參數。類模板、還能夠有非類參數的參數,通常稱之爲函數類型參數,一個模板類能夠有多個函數類型參數,全部的參數用逗號分開。element
1 template<class T,int x,float Y> 2 class Sample { 3 //... 4 };
7,示例程序:模板堆棧類
1 // stack 2 template<class T> 3 class Stack { 4 public: 5 enum{ DefaultSize = 50,EmptyStack = -1}; 6 Stack(); 7 Stack(int); 8 ~Stack(); 9 void push( const T&); 10 T pop(); 11 T getNoPop() const; 12 bool empty() const; 13 bool full() const; 14 private: 15 T* elements; 16 int top; 17 int size; 18 void allocate() { 19 elements = new T[size]; 20 top = EmptyStack; 21 } 22 void msg(const char* m) const { 23 cout << "***** "<<m<<" *****"<<endl; 24 } 25 template<class T> 26 friend ostream& operator<<(ostream& os,const Stack<T>&); 27 }; 28 29 // Stack 類的實現 30 template<class T> 31 Stack<T>::Stack() { 32 size = DefaultSize; 33 allocate(); 34 } 35 36 template<class T> 37 Stack<T>::Stack(int s) { 38 if(s < 0) 39 s *= -1; 40 else if(s == 0) 41 size = DefaultSize; 42 size = s; 43 allocate(); 44 } 45 46 template<class T> 47 Stack<T>::~Stack() { 48 delete[] elements; 49 } 50 51 template<class T> 52 void Stack<T>::push(const T& e) { 53 assert(!full()); 54 if(!full()) 55 elements[++top] = e; 56 else 57 msg("Stack full!"); 58 } 59 60 template<class T> 61 T Stack<T>::pop() { 62 assert(!empty()); 63 if(!empty()) 64 return elements[top--]; 65 else { 66 msg("Stack empty!"); 67 T dummy_val; 68 return dummy_val; // 返回一個不肯定的值 69 } 70 } 71 72 template<class T> 73 T Stack<T>:: getNoPop() const { 74 assert(top > EmptyStack); 75 if(!empty) 76 return elements[top]; 77 else { 78 msg("Stack empty!"); 79 T dummy_val; 80 return dummy_val; 81 } 82 } 83 84 template<class T> 85 bool Stack<T>::empty() const { 86 return top <= EmptyStack; 87 } 88 89 template<class T> 90 bool Stack<T>::full() const { 91 return top + 1 >= size; 92 } 93 94 template<class T> 95 ostream& operator<<(ostream& os,const Stack<T>& s) { 96 s.msg("Stack contents:"); 97 int t = s.top; 98 while(t > s.EmptyStack) 99 cout<<s.elements[t--]<<endl; 100 return os; 101 } 102 103 int main() { 104 Stack<int> stk(1); 105 stk.push(1); 106 cout<<stk<<endl; 107 108 return 0; 109 }
8,函數模板
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 // this is a function template 6 template<class Type> 7 Type maxValue(Type a,Type b) { 8 return a > b ? a : b; 9 } 10 11 int main(){ 12 stack<int> intStack; // 類模板的實例化只能由程序員顯式指定 13 cout <<"模板函數隱式調用:" << maxValue(1,2) << endl; 14 cout << "模板函數顯式調用:" << maxValue<double>(1.1,2.2) <<endl; 15 return 0; 16 }
note:類模板只能經過顯式的調用生成模板類; 函數模板能夠經過顯式調用或隱式調用生成模板函數。