模版-----是为了让代码更加通用,使代码不受数据类型的影响。减少代码冗余。模版将数据类型当作一个参数进行传递。包括函数模版和类模板。
函数模版:
//定义一个比较大小的函数模版 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,模版会推导出Type是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,则在析构函数中使用deletesize--;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; }