概述
模板是一种参数化的多态工具。所谓参数化的多态性,是指将程序所处理的对象的类型参数化,使一段程序代码可以用于处理多不同类型的对象。采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享的机制。
1、函数模板:
(1)一般说明形式:
template <模板形参表>
返回值类型函数名(模板函数形参表)
{
//函数定义体
}
注:①函数模板的定义以关键字template开头
②template之后<>中是函数模板的参数列表
③函数模板的参数是类型参数,其类型为class或typename
(2)语法:
①模板形参在模板中作为一种类型使用,可用于函数形参、函数返回值和函数局部变量;
②每个模板形参要在函数的形参列表中至少出现一次;
③模板参数名的作用域局限于函数模板的范围内;
④函数模板拥有类型模板参数、非类型模板参数。
2、函数模板示例:
//类型模板参数:T X
//非类型模板参数:num
template
void print(const T &t, const X &x)
{
// X temp;
// cin >> temp;
cout << t << endl;
cout << x << endl;
cout << num << endl;
}
int main()
{
……
(1,"hello"); //有<>显式调用,无则为隐式
//隐式调用:编译器自动推理参数类型;显示调用:使用时指定参数类型
……
}
3、模板会被编译两次:
(1)实例化模块函数之前,编译检查函数模板的语法问题;
(2)实例化模块函数之后,编译检查模板函数的语法问题。
4、应用--实现代码功能的复用性:(以输出最大值为例)
(1)函数重载:函数版本较多,后期维护麻烦,导致代码体系过于庞大。
int max(int a, int b){return a > b ? a : b;}
int max(string a, string b){ return a > b ? a : b;}
int max(A a, B b){ return a > b ? a : b;}
(2)宏函数:不安全,不做类型检查,只做傻瓜式替换,不适合实现过于复杂的函数。
#define MAX(a,b) a > b ? a : b
(3)模板:解决了函数重载版本过多、宏函数不安全及不适合复杂函数的问题。
template
T MyMax(const T &a, const T &b)
{
return a > b ? a : b; //三目运算符:返回最终最大的数
}
int main()
{
……
cout << MyMax
(5,6) << endl; //通过<>自动实例化生成模板函数:int MyMax(const int &a, const int &b)
cout << MyMax
('a','b') << endl; //char MyMax(const char &a, const char &b) cout << MyMax
("hello","world") << endl; ……
}
1、类模板:
(1)一般说明形式:
①类内实现
template <类型形参表>
class <类名>
{
//类说明体
}
②类外实现
class <类名>{};
template < 类型形参表>
<返回类型> <类名> <类型名表>::<成员函数1> (形参表)
{
//成员函数定义体
}
template < 类型形参表>
<返回类型> <类名> < 类型名表>::<成员函数2> (形参表)
{
//成员函数定义体
}
……
template < 类型形参表>
<返回类型> <类名> < 类型名表>::<成员函数n> (形参表)
{
//成员函数定义体
}
(2)语法:
①类模板的实例化:用具体的数据类型替换模板的参数以得到具体的类(模板类)。
②模板类也可以实例化为对象。
③用下列方式创建类模板的实例:
类名<类型实参表>对象名称;
④类模板可以有非类型模板参数;
⑤类模板可以有缺省值。
2、类模板会实例化两次:
(1)将类模板实例化为模板类;
(2)通过模板类实例化对象。
3、示例:(使用缺省值后的代码)
#include
#include
#include
#include
//define MAX_SIZE 1024
using namespace std;
class A
{
public:
A()
{
}
int num;
};
//template
template >
class Stack
{
public:
Stack()
{
top = -1;
// memset(data,0,sizeof(data));
}
void push(T num)
{
// top ++;
// data[top] = num;
data.push_back(num);
}
T pop(T num)
{
// return data[top --];
return data.pop_back();
}
private:
int top;
// T data[MAX_SIZE];
CONT data; // == vector data;
};
int main()
{
Stack s1;
s1.push(5);
Stack s2;
s2.push("hello");
A a;
Stack s3;
s3.push(a);
return 0;
}