前言
函数模板和类模板的出现绝非偶然,而是随着编程越来越庞大的代码,大量重复冗余的代码,创造者运用自己的聪明才智而发明的类似于工具一样的技术手段。想象一下如果下面这个场景:
你的老板对你说,客户想要两个整数相加的结果,于是
int add(int a, int b)
{
return a + b;
}
结果第二天,客户又想要浮点数相减,于是
float add(floata, floatb)
{
return float - float;
}
接下来的场景大家都能想到了,什么char, string, double。。。
float add(floata, floatb)
{
return float - float;
}int add(int a, int b)
{
return a + b;
}double add(double a, double b)
{
return a*b;
}
.........
看到这里,你可能会产生疑惑了,明明这些代码做的事情都一样,参数和返回类型都是一样的,还写了这么多遍,造成了很严重的代码冗余,所以啊,聪明的设计者就发明了一种叫做模板的东西,具体如下:
template<typename T>
T add(T a, T b)
{
return a + b;
}
相比上面看上去是不是简单了许多,减少了大量的冗余代码,极大地提升了代码的可重用性
类模板
template<class T>
class Calculator
{
private:
T leftValue;
T rightValue;public:
Calculator() {}
Calculator(T a, T b) : leftValue(a), rightValue(b) {}
T add();
T minus();
T multiply();
T divide();
};template <class T>
T Calculator<T>::add()
{
return leftValue + rightValue;
}template <class T>
T Calculator<T>::minus()
{
return leftValue - rightValue;
}template <class T>
T Calculator<T>::multiply()
{
return leftValue * rightValue;
}template <class T>
T Calculator<T>::divide()
{
assert(!(0 == rightValue));
return leftValue / rightValue;
}int main()
{
Calculator<int> cal; //当我们使用模板类的时候,必须提供一个显示模板形参列表,它们被绑定到模板形参。编译器会使用这个
//列表实例出特定的类。一个类模板的每一个实例都是一个特定的类
auto sum = cal.add(1,2);
}
需要注意的是:与以往我们编写类不同的是,普通类都是类的定义在头文件,供其他文件引用,成员函数的定义放在相应的.cpp文件中。而模板不同:为了生成一个实例化版本,函数模板或类模板需要掌握函数或成员函数的定义,所以模板的声明和定义都需要放在头文件