模板机制
C++提供两种模板机制:函数模板、类模板
类属----类型参数化,又称参数模板:使得程序或算法可以从逻辑功能上抽象,把被处理的对象类型或数据类型作为参数进行传递
模板把函数或类要处理的数据类型参数化,表现为参数的多态性,称为类属。
模板用于表达逻辑结构相同,但具体数据元素类型不同的数据对象的通用行为
函数模板语法
template <类型形式参数表>
类型 函数名(形式参数表){
}
例如:
template 告诉C++编译器我们要开始泛型编程了,看到T不要报错,它指得是一种数据类型
<>中可以有多个typename ,比如<typename T,typename G>;但定义了就一定要用!!
template
void myswap(T &a,T &b) {
T c;
c = a;
c = b;
b = c;
}
函数模板的调用
1)显示类型调用 myswap(x, y);
2)自动类型推导(不常用) myswap(x, y);
函数模板遇到函数重载
函数模板和普通的函数有什么区别的嘛?
template <typename T>
void myswap(T &a, T &b) {
T c = a;
a = b;
b = c;
}
void myswap(int a, char c) {
cout << "普通函数!!" << endl;
}
void main()
{
int a = 10;
char b = 'z';
//调用哪个? 普通函数
myswap(a, b);
//调用哪个? 普通函数
myswap(a, a);
//调用哪个? 函数模板
myswap(b, a);
}
调用函数模板的本质是类型参数化,将严格的按照类型进行匹配,不会进行自动类型转换
普通函数调用可以进行隐式的类型转换
函数模板可以像普通函数一样被重载
C++编译器优先考虑普通函数
如果函数模板可以产生更好的匹配,则选择函数模板
可以通过空模板实参列表的语法限定编译器只通过模板匹配
C++编译器函数模板机制原理
编译器并不是把函数模板处理成能够处理任何类型的函数
编译器从函数模板通过具体类型产生不同的函数
编译器会对函数模板进行两次编译:在声明的地方对模板代码本身进行编译;在调用的地方对参数进行替换后的代码进行编译
其实就是C++编译器帮程序员根据函数模板生成了需要参数类型的函数原型!!!
为什么要用类模板
和函数模板同理,当多个类功能一样,仅仅是其中的数据类型不同时需要类模板。
类模板用于实现类所需数据的类型参数化
类模板在表示如数组、表、图等数据结构时特别重要
模板类本身就是抽象的(类型化的),使用时必须进行类型具体化
抽象的模板类---->具体的类----->具体的对象
子模版类派生时,需要具体化模板类C++编译器需要知道父类的数据类型具体是什么样的。因为继承时需要启用父类的构造函数,C++编译器需要知道父类所占的内存大小是多少。只有数据类型固定才能知道如何分配内存