模版-----是为了让代码更加通用,使代码不受数据类型的影响。减少代码冗余。模版将数据类型当作一个参数进行传递。包括函数模版和类模板。
函数模版:
//定义一个比较大小的函数模版 template<typename Type> // 也可以写成 template <class Type> Type Max(Type a,Type b) { return a > b ? a : b; } int main() { cout << Max(1,2) << endl; cout << Max(‘A‘, ‘a‘) << endl; cout << Max(2.5,3.2) << endl; return 0; }
模版会根据传递的实参自动进行数据类型的推演,比如在Max(2.5,2.3)中,模版会根据2.5是double,2.3是double,模版会推导出ype是double类型,生成一个模版函数,使用double类型的比较函数。所以模版虽然方便,但是效率不高。
比如,调用函数Max(1,2)时,编译器会先生成一个int类型的模版函数。然后再去调用具体的模版函数。
//模版函数
int Max(int a, int b) { return a > b ? a : b }
当出现实参类型不一致时,普通函数正常运行,模版会出现错误,如:
/*
template<typename Type> //会产生二义性 Type Max(Type a,Type b) { return a > b ? a : b; }
*/ int Max(int a,int b) //会自动进行隐式转换 { return a > b ? a : b; } int main() { cout << Max(1,2.3) << endl;
cout << Max(1,(int)2.3) << endl; //将2.3强制转换成int类型
cout << Max<int>(1,2.3) << endl; //指定调用int类型的模版函数 }
也可以重新编写模版函数,如:
template<typename Type1, typename Type2> Type2 Max(Type1 a,Type2 b) { return a > b ? a : b; }
如果是类对象进行比较,需要重载比较运算符。模版只负责比较,不管如何进行比较。
class Test { int num; public: Test(int b):num(b){} bool operator>(const Test & t) { if (this->num > t.num) return true; else return false; } }; template<typename Type1> Type1 Max(Type1 a,Type1 b) { return a > b ? a : b; } int main() { Test t1(10); Test t2(9); Max(t1,t2); //不能使用cout输出,因为没有提供<<运算符函数 }
类模板:
利用类模板简单实现线性链表。
int a = int(); //将a初始化为0;
模版类成员函数都是模版函数,不允许将类定义和实现分离
#include <iostream> using namespace std; //声明List类 template<typename Type> class List;
template<typename Type> class ListNode { private: Type data; ListNode<Type> *next; public: friend class List<Type>; //将List类成为ListNode类的友元类,才能访问私有数据 ListNode():data(Type()),next(NULL){} //零初始化:根据不同类型进行初始化。如,int a = int() //a被初始化为0。 ListNode(Type d,ListNode<Type> *n = NULL):data(d),next(n){} ~ListNode(){} }; template<typename Type> class List { private: ListNode<Type> *first; ListNode<Type> *last; size_t size; public: List(); ~List(); bool push_back(Type x); //尾部插入链表
//显示列表函数 void Show_list() const //模版类的成员函数可以在类内部定义 { ListNode<Type> *p=first; while(p != NULL) { cout << p->data; p = p->next; } } }; template<typename Type> //模版类的成员函数都是模版函数,所以必须写template<typename Type> List<Type>::List() //限定是List<Type>:: { first = last = new ListNode<Type>; last->next = NULL; size=0; } template<typename Type> List<Type>::~List() { ListNode<Type> *p=first; while(p != NULL) { first = p->next; delete p; //在构造函数中使用new,则在析构函数中使用delete size--; p=first; } } template<typename Type> bool List<Type>::push_back(Type x) { ListNode<Type> *s = new ListNode<Type>; if( s == NULL ) return false; s->data = x; s->next = NULL; last->next = s; last = s; return true; } int main() { List<int> mylist; for(int i=1;i<10;i++) { mylist.push_back(i); } mylist.Show_list(); return 0; }