1 类模板
C++ 将模板的思想应用于类,使得类的实现不再关注数据元素的具体类型,而只管组类所需要实现的功能,一些类主要用于存储组织数据元素,如数组类,链表类,Stack 类,Queue 类
同样的,在类声明前使用 template 进行标识,语法如下:
1.1 类模板的应用
- 只能显示指定具体类型,无法自动推导
- 使用具体类型<Type>定义类型
1.2 编译器对类模板的处理
- 通过具体类型产生不同的类
- 在声明的地方对类模板本身进行编译
- 在使用的地方对参数替换后的代码进行编译
// 43-1.cpp
#include<iostream>
#include<string>
using namespace std;
template<typename T>
class Operator
{
public:
T add(T a, T b) { return a + b; }
T minus(T a, T b) { return a - b; }
T multiply(T a, T b) { return a * b; }
T divide(T a, T b) { return a / b; }
};
string operator - (string& l, string& r) // 重载'-'操作符,这里就是为了编译通过
{
return "Minus";
}
int main()
{
Operator<int>op1; // 显示指定具体类型
cout << op1.add(1, 2) << endl;
Operator<string>op2; // 显示指定具体类型
cout << op2.add("Let's ", "go!") << endl;
cout << op2.minus("Let's ", "go!") << endl;
return 0;
}
编译器编译时,首先对类本身进行编译,如代码第 5-13 行;创建具体的类时也要进行编译,代码 20、22 行;当使用成员函数时也要进行编译,如第 21、23、24 行。如果我们不重载减号操作符,第 24 行将编译出错,但是第 22 行可以编译通过。这也说明了生成具体类时要编译,调用成员函数也要编译。
$ g++ 43-1.cpp -o 43-1
$ ./43-1
3
Let's go!
Minus
2 类模板的工程应用
- 类模板必须在头文件中定义
- 类模板在同一个文件中实现
- 类模板外部定义的成员函数需要加上模板<>声明
// Operator.h
#ifndef _OPERATOR_H_
#define _OPERATOR_H_
template<typename T>
class Operator
{
public:
T add(T a, T b);
T minus(T a, T b);
T multiply(T a, T b);
T divide(T a, T b);
};
template<typename T>
T Operator<T>::add(T a, T b)
{
return a + b;
}
template<typename T>
T Operator<T>::minus(T a, T b)
{
return a - b;
}
template<typename T>
T Operator<T>::multiply(T a, T b)
{
return a * b;
}
template<typename T>
T Operator<T>::divide(T a, T b)
{
return a / b;
}
#endif
// 43-2.cpp
#include<iostream>
#include"Operator.h"
using namespace std;
int main()
{
Operator<int>op1;
cout << op1.add(1, 2) << endl;
cout << op1.multiply(4, 5) << endl;
cout << op1.minus(5, 6) << endl;
cout << op1.divide(10, 5) << endl;
return 0;
}
类模板的声明与定义应在同一个问价中,类模板外部定义的成员函数需要加上模板<>声明
编译运行
$ g++ 43-2.cpp -o 43-2
$ ./43-2
3
20
-1
2
3 小结
1、类模板使用时只能显示指定类型
2、编译器在声明的地方和使用的地方进行编译
3、类模板在同一个文件中实现