1 问题的提出
-- 为了多快好省地定义出一批相似的类,可以定义类模板,然后由类模板生成不同的类
-- 数组是一种常见的数据类型,元素可以是:
- 整数
- 学生
- 字符串
- ......
-- 考虑一个数组类,需要提供的基本操作
- len():查看数组的长度
- getElement(int index); 获取其中的一个元素
- setElement(int index); 对其中的一个元素进行赋值
......
-- 这些数组类,除了元素的类型不同,其他的完全相同
2 类模板的定义
template <class 类型参数1, class 类型参数2, ......> // 类型参数表
class 类模板名
{
成员函数和成员变量
};
class 可替换成 typename 在写模板函数的时候也可以替换
template <typename 类型参数1, typename 类型参数2, ......>
class 类模板名
{
成员函数和成员变量
};
3 类模板中成员函数的写法:
template <class 类型参数1, 类型参数2, ......> // 类型参数表
返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)
{
......
}
4 类模板定义对象的写法:
用类模板定义对象的写法:
类模板名<真实类型参数表> 对象名(构造函数实参表);
5 类模板实例:(见本工程leimubaneg1.cpp)
/**
* 类模板例子
* Pair类模板
*/
#include <iostream>
using namespace std;
template <class T1, class T2>
class Pair
{
public:
T1 key; // 关键字
T2 value; // 值
Pair(T1 k, T2 v):key(k), value(v){}
// 该重载用来比大小,因此参数为同类另外一个对象的常引用 const Pair<T1, T2>& p
// 小于号最好是const的,因此在最后加const关键字
bool operator< (const Pair<T1, T2>& p) const;
};
template <class T1, class T2>
bool Pair<T1, T2>::operator<(const Pair<T1, T2> &p) const {
return key < p.key;
}
int main()
{
Pair<string, int> student("Tom",19);
// 实例化出一个类Pair<string, int>
cout << student.key << " " << student.value;
return 0;
}
6 编译器由类模板生成类的过程叫类模板的实例化。由类模板实例化得到的类,叫模板类
-- 同一个类模板的两个模板类是不兼容的
Pair<string, int>* p;
Pair<string, double> a;
p = &a; // wrong
7 函数模板作为类模板的成员(见本工程leimubaneg2.cpp)
/**
* 函数模板作为类模板的成员例子
*/
#include <iostream>
using namespace std;
template <class T>
class A
{
public:
template <class T2>
void Func(T2 t)
{
cout << t; // 成员函数模板
}
};
int main()
{
A<int> a;
// void A<int>::Func(char c);
a.Func('K'); // 成员函数模板Func被实例化
// void A<int>::Func(const char* p);
a.Func("hello"); // 成员函数模板Func再次被实例化
return 0;
}
8 类模板的“<类型参数表>”中可以出现非类类型参数:
template <class T, int size>
class CArray
{
T array[size];
public:
void Print()
{
for(int i = 0; i < size; ++i)
cout << array[i] << endl;
}
};
CArray<double, 40> a2;
CArray<int, 50> a3; // a2和a3属于不同的类