模版编程--类模版
类模版
1、模版编程也叫泛型编程,及不指定类型,当用时在标明类型。
2、模版类函数最好吧声明和定义写在一起,这样不至于在每个函数前都声明模版。
3、在编译时,编译器会自动处理模版类的重定义问题,所以不用进行模版类的预处理。
4、模版类可以特殊化,如下例:
1 #include <iostream> 2 using namespace std; 3 #include <typeinfo> 4 template < typename T=int, int len=10 > 5 class Stack{ 6 T a[len]; 7 int cur; 8 public: 9 const char* element()const{return typeid(T).name();} 10 int max_size()const{return len;} 11 Stack():cur(0){} 12 void push(const T& d)throw(const char*){//数据入栈成为栈顶 13 if(full()) throw "满"; 14 a[cur++] = d; 15 } 16 T pop()throw(const char*){//栈顶数据出栈,下一个数据成为栈顶 17 if(empty()) throw "空"; 18 return a[--cur]; 19 } 20 const T& top()const throw(const char*){//取得栈顶数据 21 if(empty()) throw "空"; 22 return a[cur-1]; 23 } 24 bool empty()const{return cur==0;}//是否空栈 25 bool full()const{return cur==5;}//是否已满 26 void clear(){cur=0;}//栈清空(复位) 27 int size()const{return cur;}//栈中数据个数 28 }; 29 template <int len> 30 class Stack<const char*,len>{//部分特化 31 string a[len]; 32 int cur; 33 public: 34 const char* element()const{return "const char*";} 35 int max_size()const{return len;} 36 Stack():cur(0){} 37 void push(const char* d)throw(const char*){//数据入栈成为栈顶 38 if(full()) throw "满"; 39 a[cur++] = d; 40 } 41 const char* pop()throw(const char*){//栈顶数据出栈,下一个数据成为栈顶 42 if(empty()) throw "空"; 43 return a[--cur].c_str(); 44 } 45 const char*& top()const throw(const char*){//取得栈顶数据 46 if(empty()) throw "空"; 47 return a[cur-1].c_str(); 48 } 49 bool empty()const{return cur==0;}//是否空栈 50 bool full()const{return cur==len;}//是否已满 51 void clear(){cur=0;}//栈清空(复位) 52 int size()const{return cur;}//栈中数据个数 53 }; 54 int main() 55 { 56 Stack<int> i; 57 i.push(1);i.push(2);i.push(3); 58 while(!i.empty()) cout << i.pop() << endl; 59 char buf[100]; 60 Stack<const char*> s; 61 for(;;){ 62 cin >> buf; 63 if(strcmp(buf,"end")==0) break; 64 s.push(buf); 65 } 66 cout << "=============" << endl; 67 while(!s.empty()) cout << s.pop() << endl; 68 }
1、模版类也可以当做函数使用,例如用于递归,当n等于0和不等于0两种情况时。
2、模版类比较灵活,会自动搜寻与他匹配的类型,比如类型或指针匹配。
1 #include <iostream> 2 using namespace std; 3 #include <typeinfo> 4 template <int n> 5 class Fact{ 6 public: 7 enum {val=Fact<n-1>::val*n}; 8 }; 9 template <> 10 class Fact<0>{ 11 public: 12 enum {val=1}; 13 }; 14 template < typename T > 15 class Type{ 16 public: 17 static string name(){return typeid(T).name();} 18 }; 19 template <> 20 class Type<char>{ 21 public: 22 static string name(){return "char";} 23 }; 24 template <> 25 class Type<double>{ 26 public: 27 static string name(){return "double";} 28 }; 29 template <> 30 class Type<int>{ 31 public: 32 static string name(){return "int";} 33 }; 34 template <> 35 class Type<bool>{ 36 public: 37 static string name(){return "bool";} 38 }; 39 template <typename T> 40 class Type<T*>{ 41 public: 42 static string name(){return Type<T>::name()+" pointer";} 43 }; 44 45 int main() 46 { 47 cout << Fact<5>::val << endl; 48 cout << Type<double>::name() << endl; 49 cout << Type<char>::name() << endl; 50 cout << Type<bool>::name() << endl; 51 cout << Type<int*>::name() << endl; 52 cout << Type<double*>::name() << endl; 53 cout << Type<bool**>::name() << endl; 54 }