1 类模板
类模板是在类的定义时,不能确定成员的类型时,为了防止代码的冗余,用T代替。
T是一个类型,告诉编译器,类型还没有绑定,不知道现在是什么类型。使用的时候,类名后要用尖括号把类型名括起来。
Complex<int> a(1,2);
Complex<double> a(1.0,2.0);
当编译时,编译器看到了使用者的T是一种类型时(如int),则将类中全部的T替换为此类型(T全变为int),得到一份代码。
当T时不同的n种类型时,会得到n种不同的代码。因此模板会造成代码的膨胀,但这是必要的。
template <typename T>
class complex
{
public:
complex(T r = 0, T i = 0)
:re(r), im(i)
{}
complex& operator += (const complex&);
T real() const { return re; }
T imag() const { return im; }
private:
T re, im;
friend complex__doapl(complex* , const complex& );
};
2 函数模板
函数模板用于一个操作不知道是对哪种类型的对象来操作的情况。如比大小这个操作min,可以对数字,也可以对人,还可以对石头进行。这时使用函数模板可以减少代码冗余。代码如下:
template <class T>
inline
const T& min(const T& a, const T& b)
{
return b < a ? b : a;
}
以对石头比大小为例:
stone r1(2,3), r2(3,3), r3;
r3 = min(r1,r2);
这里,编译器会对函数模板进行实参推导,发现应该对函数绑定为stone类型,将生成一份T全部替换为stone的代码。
于是,根据"<"的使用,调用 stone::operator< 这一函数。在stone类中寻找如下:
class stone
{
public:
stone(int w, int h, int we,)
:_w(w), _h(h), _weight(we)
{ }
bool operator< (const stone& rhs) const
{ return _weight < rhs._weight; }
private
int _w, _h, _weight;
};