人们需要编写多个形式和功能都相似的函数,因此有了函数模板来减少重复劳动;人们也需要编写多个形式和功能都相似的类,于是 C++ 引人了类模板的概念,编译器从类模板可以自动生成多个类,避免了程序员的重复劳动。
一、定义
所谓 类模板(class template )是「包含一个或多个尚未确定之类型」的 类。我们必须将具体类型当作 template arguments 传入,才能使用 class template。于是该 class template我们所指定的那些类型,由编译器加以实例化并编译。class templates 之中,只有实际被调用的成员函数,才会被实例化。
二、公式
C++ 中类模板的写法如下:
template <类型参数表>
class 类模板名{
成员函数和成员变量
};
类模板中的成员函数放到类模板定义外面写时的语法如下:
template <类型参数表>
返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)
{
...
}
三、实例
//该Stack类定义在stack.hpp文件中
template <typename T>
class Stack//定义类模板
{
private:
std::vector<T> elems; // 元素
public:
void push(T const&); // push 元素
void pop(); // pop 元素
T top() const; // 传回最顶端元素
bool empty() const { // stack是否为空
return elems.empty();
}
};
template <typename T>//成员函数
void Stack<T>::push(T const& elem)
{
elems.push_back(elem); // 追加(附于尾)
}
template <typename T>
void Stack<T>::pop()
{
if (elems.empty()) {
throw std::out_of_range("Stack<>::pop: empty stack");
}
elems.pop_back(); // 移除最后一个元素
}
template <typename T>
T Stack<T>::top() const
{
if (elems.empty()) {
throw std::out_of_range("Stack<>::top: empty stack");
}
return elems.back(); // 传回最后一个元素的拷贝
}
四、使用
#include <iostream>
#include <string>
#include <cstdlib>
#include "stack.hpp"
int main()
{
try
{
Stack<int> intStack; // stack of ints
Stack<std::string> stringStack; // stack of strings
// 操控 int stack
intStack.push(7);
std::cout << intStack.top() << std::endl;
// 操控 string stack
stringStack.push("hello");
std::cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (std::exception const& ex) {
std::cerr << "Exception: " << ex.what() << std::endl;
return EXIT_FAILURE; // 传回错误状态码
}
}