一、函数模板
- 函数模板属于类属,使用模板可以实现用一个函数体就可以处理不同的数据类型。
- 函数模板并不是一个真正意义上的函数,它仅仅是对函数结构外观的声明,本身并不占用内存,只有当编译器遇到模板函数的调用时,才会在内存中创建一个函数实例。
- 函数模板有点类似于重载,但是比重载更加方便。
- c++不但支持函数重载,也支持函数模板重载。与函数重载类似,模板重载也是根据形参列表进行区分。
考虑如下程序:
#include <iostream>
using namespace std;
//定义一个函数模板
template <class T> //类型参数表的开始符是class,也可以是typename,后面的T表示数据类型
T square(T number) //在下面的函数调用时,编译器将采用合适的数据类型代替T
{
return number*number;
}
//模板重载
//下面接收两个参数,计算num1的num2次方
template <class T>
T square(T num1,T num2)
{
T buff = 1;
for(int i=0;i<num2;i++)
{
buff=buff*num1;
}
return buff;
}
int main()
{
int y1,x1=4;
float y2,x2=0.4;
y1 = square(x1);
cout << "square of 4 is:" <<y1<< endl;
y2 = square(x2);
cout << "square of 0.4 is:" <<y2<< endl;
y2 = square(2,3);
cout<<"调用重载的函数,2的3次方等于:"<<y2;
return 0;
}
运行结果:
要想简单的定义一个模板,可以先定义一个函数,确定这个函数没有错误之后,在将其转换为模板。
也就是在前面加上template <class T>,然后将函数中的类型关键字替换成T即可。
二、类模板
- 类模板用于创建类属类和抽象数据类型,从而使程序员可以创建一般形式的类,而不必编写处理不同数据类型的类。
- 类模板的定义和函数模板定义类似,也是在前面加上template <class T>,然后将整个类中需要改变的数据类型用T替代。
- 利用类模板实例化对象的时候需要注意格式:在类的后面加<类型说明>
eg:
//利用类模板实例化两个不同的对象
FreeArray<int> arrInt(10);
FreeArray<float> arrFloat(10);
注意:
- 编译器遇到类模板时并不为他分配内存空间,直到定义了一个模板对象,也就是模板参数由编译器替换时,才为其分配空间。
- 由于许多编译器还不支持类模板的定义和实现分开,因此最好将类模板的定义和实现放在同一个文件中。
考虑如下程序:
类模板的定义与实现,实现一个数组类的抽象数据类型:
template <class T>
class FreeArray
{
private:
T *aptr;
int arraySize;
void memError(void);
void subError(void);
public:
FreeArray(void){aptr=0;arraySize=0;}
FreeArray(int);
FreeArray(const FreeArray &);
~FreeArray(void);
int sizeArray(void){return arraySize;}
T &operator[](const int &);
};
//内存分配错误时处理函数
template <class T>
void FreeArray<T>::memError(void)
{
cout<<"error,the storage is filled\n";
exit(0);
}
//下标越界时的错误
template <class T>
void FreeArray<T>::subError(void)
{
cout<<"error,the subindex is error\n";
exit(0);
}
//类模板的构造函数,设置数组大小,并对数据分配内存
template <class T>
FreeArray<T>::FreeArray(int s)
{
arraySize = s;
aptr = new T [arraySize];
if(aptr == 0)memError();
for(int a=0;a<arraySize;a++)
{
*(aptr+a) = 0;
}
}
//类模板的拷贝构造函数
template <class T>
FreeArray<T>::FreeArray(const FreeArray &obj)
{
arraySize = obj.arraySize;
aptr = new T [arraySize];
if(aptr == 0)memError();
for(int a=0;a<arraySize;a++)
{
*(aptr+a) = *(obj.aptr + a);
}
}
//类模板的析构函数
template <class T>
FreeArray<T>::~FreeArray(void)
{
if(arraySize > 0)
delete [] aptr;
}
//重载运算符[]
template <class T>
T &FreeArray<T>::operator[](const int &sub)
{
if(sub<0 || sub>arraySize)
subError();
return aptr[sub];
}
主函数:
//利用类模板实例化两个不同的对象
FreeArray<int> arrInt(10);
FreeArray<float> arrFloat(10);
int x;
//为数组元素赋值
for(x = 0;x<10;x++)
{
arrInt[x] = x;
arrFloat[x] = x+0.1;
}
//输出数组元素
cout<<"the value of int array is:";
for(x=0;x<10;x++)
cout<<arrInt[x]<<" ";
cout<<"\nthe value of float array is:";
for(x=0;x<10;x++)
cout<<arrFloat[x]<<" ";
cout<<endl;
return 0;
运行结果: