模板的使用比较频繁,所以这里总结一下,后面有新的收获会及时更新。
1 模板概述
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。
模板是创建泛型类或函数的蓝图或公式。
2 模板格式
//函数模板
template <class type> ret-type func-name(paramter list)
{
//函数的主体
}
//在这里,type是函数所使用的数据类型的占位符名称。
//这个名称可以在函数定义中使用。
//类模板
template <class type> class class-name
{
//类的主体
}
//在这里,type 是占位符类型名称,可以在类被实例化的时候进行指定。
//可以使用一个逗号分隔的列表来定义多个泛型数据类型。
3 模板技术
类型参数化,编写代码可以忽略类型
为了让编译器区分是普通函数,模板函数,通过template。
template<class T>
或者template<typename T>
【注意】:
(1)template只对后面的第一个函数生效;
(2)尖括号内的参数可以不止一个;
(3)调用时,可以自动类型推导,或者显示指定类型——在函数名后面加<数据类型>。
4 函数模板和普通函数的区别
○ 函数模板不允许自动类型转化;
○ 普通函数能够自动进行类型转化。
函数模板和普通函数在一起调用规则:
○ 函数模板可以像普通函数那样可以被重载;
○ C++编译器优先考虑普通函数;
○ 如果函数模板可以产生一个更好的匹配,那么选择模板;
○ 可以通过空模板实参列表的语法限定编译器只能通过模板匹配。【如,add<>(a,b),中间的尖括号就是空模板实参列表,这样就只能通过模板匹配】
5 函数模板机制结论
- 编译器并不是把函数模板处理成能够处理任何类型的参数;
- 函数模板通过具体类型产生不同的函数;
- 编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译。
6 类模板
类模板必须显示指定类型;
1)类模板派生普通类
class Person{
public:
Person(){
mAge=0;
}
public:
T mAge;
class SubPerson : public Person<int>{
};
2)类模板派生类模板
template<class T>
class Cat:public Animal<T>{
};
7 类模板类外实现
template<class T>
Person<T>::Person(T age,T id){
this->mID=id;
this->mAge=age;
}
template<class T>
void Person::Show(){
cout<<"Age:"<<mAge<<"ID:"<<mID<<endl;
}
注意:
1)加templete;
2)Person类后需要<T>;
8 类模板h和cpp分离编写分析
注意与【普通类的h和cpp分离编写方式】不同。
对于类模板的分离编写,不推荐,会出错。建议直接在头文件中实现,后缀名可以将.h
改成hpp
。
9 类模板中的static关键字
- 从类模板实例化的每一个模板类有自己的类模板数据成员,该模板的所有对象共享一个static数据成员;
- 和非模板类的static数据成员一样,模板类的static数据成员也应该在文件范围定义和初始化;
- 每个模板类有自己类模板的static数据成员的副本。