此篇日记以模板函数为例,引入“引用参数,常量引用参数、返回值、重载函数”的应用。
写一个两个整数相加的函数。
int add(int a,int b)
{
return a+b;
}
此时又需要一个单精度浮点类型的两个数相加的函数。
float add(float a,float b)
{
return a+b;
}
两者如果包含在同一个程序中,显然会有冗余,但两者又必不可少,此时引入模板函数的概念。
template <class T>
T add(T a,T b)
{
return a+b;
}
函数类型、形参类型均用T代替,编译器可根据实参的数据类型构造出能够进行不用数据类型加法的程序。
在上面的程序中,我们以传值的形式构造了函数,但是由于传值过程中,复制构造函数,析构函数运行浪费时间,并且形参的复制要浪费空间,这里运用了“引用参数”的方式进行优化。
template <class T>
T add(T& a,T& b)
{
return a+b;
}
引用参数类似于传址调用,并不进行参数的复制,快速且节约空间。但是引用参数后,函数内部便可对于实参进行修改,虽然上述的代码段没有修改,但保险起见,需要继续优化,此时引入“常量引用参数”
template <class T>
T add(const T& a,const T& b)
{
return a+b;
}
用关键字const来指明函数不可修改引用的参数。
函数模板使用后,函数返回值类型,函数所有参数由第一个参数决定,在上述代码段中“T add(const T& a,const T& b)”即:第一个参数a决定函数返回值以及另一个参数b的类型,如果需要不同类型的参数以及返回值,可做以下优化:
template <class Ta,class Tb>
Ta count(Ta a,Tb b)
{
}
这样,仅函数返回值类型与第一个参数相同,第二个参数的数据类型是可以自由变化的。
如果在函数模板中需要用数组作为参数,可做以下改变:
template <class Ta,class Tb>
Ta count(Ta a[],Tb b)
{
}
在函数返回类型后加一个&,我们便指定了一个引用返回。
template <class T>
T& f(int i,T& a)
{
a++;
return a;
}
这种返回形式不会把a的值复制到返回环境中。函数结束后,形参i以及其他局部变量所占用的空间将会被释放,因为a仅仅是对一个实参的引用,所以他不会受到影响。因为局部变量会被释放,所以这种返回形式不适合返回局部变量等。
在C++中,函数允许重名,但任何两个同名的函数不能拥有同样的签名。定义多个同名函数的机制成为重载函数。