首页 > 代码库 > C++模板&泛型编程
C++模板&泛型编程
---恢复内容开始---
一、泛型编程
定义:编写与类型无关的逻辑代码,是代码复用的一种手段。模板是泛型编程的基础
模板分为:函数模板和类模板
函数模板:代表了一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
函数模板的格式:template<typename p1,typename p2,...,typename p> //typename和class都可以定义模板参数一般建议使用typelate好理解和类关键字区分
返回值类型 函数名(参数列表)
{...}
模板是蓝图,本身不是类或者函数,编译器用模板产生特定的类或者函数的特定类型版本,产生模板特定类型的过程成为模板的实类化
定义模板关键字:T是模板参数名字可以任意命名,下面代码返回值是T类型这个很重要
1 template<typename T> 2 T Add(T left,T right) 3 { 4 return left+right; 5 } 6 7 int main() 8 { 9 cout<<Add(1,2)<<endl;; 10 return 0; 11 }
//给main()函数里加一句cout<<Add(1.2,2.3)<<endl;函数模板将被编译两次
// 1.实类化之前,检查模板代码本身,查看是否出现语法错误,如:遗漏分号。2.在实类化期间,检查模板代码,查看是否所有的调用都有效,如:实类化理性不支持某些函数调用
这个返回值是T1,配合下面代码就是int ,函数返回值类型很重要,所以这里还是认真点
1 template<typename T1,typename T2> 2 T1 Add(T1 left,T2 right) 3 { 4 return left+right; 5 } 6 7 int main() 8 { 9 cout<<Add(1,‘2‘)<<endl;; 10 return 0; 11 }
模板函数也可以定义为inline函数
1 template<typename T1,typename T2> 2 inline T2 Add(T1 left,T2 right) 3 { 4 return left+right; 5 } 6 7 int main() 8 { 9 cout<<Add(1,‘2‘)<<endl;; 10 return 0; 11 } 12 //返回值是字符3
模板参数:
模板函数有两种类型形参:模板参数和调用参数
模板形参分为:类型形参和非类型形参
//模板形参名字只能在模板形参之后到模板声明或定义的末尾之间使用,遵循名字屏蔽规则
1 typedef int T; 2 template<typename T> 3 void FunTest(T t) 4 { 5 cout<<"t type = "<<typeid(t).name()<<endl; 6 } 7 T gloab; 8 int main() 9 { 10 FunTest(10); 11 cout<<"gloab type = "<<typeid(gloab).name()<<endl; 12 return 0; 13 }
eg:判断下面函数定义是否有问题
1 //template<class T,U,typename V> 2 //void F1(T,U,V); 3 //模板参数不能这样定义,模板参数前必须加上定义模板参数关键字class或者typeame 4 //template<class T> 5 //T F2(int &T); 6 7 //template<class T> 8 //T F3(T,T); 9 //typedef int TYPENAME; 10 //template<typename TYPENAME> 11 //TYPENAME F4(TYPENAME);
模板函数重载:
主要看看下列情况调用哪个函数
1 int Max(const int& left,const int& right)//1 2 { 3 return (left>right)?left:right; 4 } 5 template<typename T> //2 6 T Max(const T& left,const T&right) 7 { 8 return (left>right)?left:right; 9 } 10 template<typename T> //3 11 T Max(const T& a,const T& b,const T& c) 12 { 13 return Max(Max(a,b),c); 14 } 15 int main() 16 { 17 Max(10,20,30);//3 18 Max<>(10,20);//2 19 Max(10,20); //1 20 Max(10,20.0);//1 21 Max<int>(10.0,20.0);//2 22 Max(10.0,20.0);//2 23 return 0; 24 }
//注意:函数的所有重载版本的是声明都应该位于该函数被调用位置之前
二、模板函数特化
在某些情况下,通用模板定义对于某个类型可能是完全错误的,或者不能编译,或者做一些错误的事情
1 template<class T> 2 int compare(T t1,T t2) 3 { 4 if(t1>t2) 5 return 1; 6 else if(t1<t2) 7 return -1; 8 else 9 return 0; 10 } 11 int main() 12 { 13 char *pStr1="holle"; 14 char *pStr2="world"; 15 cout<<compare(pStr1,pStr2)<<endl; 16 return 0; 17 }
//结果是1,实际是-1
模板函数特化形式:
1、关键字template后面跟一个空的<>
2、再接模板名和<模板形参>
3、函数形参表
4、函数体
三、模板类
模板类型格式
template<typename p1,typename p2,...,typename p>
class 类名
{...}
eg:
1 template<typename T> 2 class SeqList 3 { 4 private: 5 T* _Data; 6 int _size; 7 int _capacity 8 }
1 //以模板方式实现动态顺序表 2 3 template<typename T> 4 class SeqList 5 { 6 public: 7 SeqList(); 8 ~SeqList(); 9 private: 10 int _size; 11 int _capacity; 12 T* _Data; 13 }; 14 template<typename T> 15 SeqList<T>::SeqList() 16 :_size(0) 17 ,_capacity(10) 18 ,_Data(new T[_capacity]) 19 {} 20 template<typename T> 21 SeqList<T>::~SeqList() 22 { 23 delete []_Data; 24 } 25 void FunTest() 26 { 27 //SeqList Seq; 28 SeqList<int>s1; 29 SeqList<double>s2; 30 }
//有一种不同的类型编译器就会实类化出对应的一个类
---恢复内容结束---
C++模板&泛型编程