1.2.1 传值参数
设计一个函数用来计算表达式a+b*c,其中a,b和C是整数,结果也是整数。
程序1-1,计算一个整型表达式
#include <iostream> using namespace std; int abc(int a, int b, int c) { return a + b * c; } int main() { cout << abc(2, 3, 4) << endl; return 0; }
a,b,c是函数abc的形参,也是传值参数。
1.2.2 函数模版
设计一个函数用来计算表达式a+b*c,其中a,b和C是浮点型,结果也是浮点型。
程序1-2,计算一个浮点型表达式
#include <iostream> using namespace std; float abc(float a, float b, float c) { return a + b * c; } int main() { cout << abc(2.1, 3.2, 4.0) << endl; return 0; }
程序1-1和程序1-2都是计算一个类似的表达式,形参类型不同。
与其对每一种可能的形参类型都编写一个相应函数的新版本,不如写一段通用代码。参数类型为一个变量,它的值由编译器来确定。
这种代码使用的是模版语句,如程序1-3所示。
程序1-3,利用模版函数计算一个表达式
#include <iostream> using namespace std; template<class T> T abc(T a, T b, T c) { return a + b * c; } int main() { cout << abc(2.1, 3.2, 4.0) << endl; return 0; }
1-3程序也只是能满足形参类型为T的计算方式。T为int型满足程序1-1的情况,为float型则满足程序1-2的情况。
设计一个更通用的版本
程序1-1-1
#include <iostream> using namespace std; template<class Ta,class Tb, class Tc> Ta abc(Ta a, Tb b, Tc c) { return a + b * c; } int main() { cout << abc(2, 3.2, 4) << endl; return 0; }
注:在新的版本中,每个形参可以是不同的数据类型,而函数返回值的类型与第一个形参类型相同。
1.2.3引用参数
程序1-3使用的形参会增加程序的运行时间。
当a,b,c是传值参数时,一进入函数调用,类型T的复制构造函数便把相应的实参分别复制给形参a,b,c。当函数返回时,类型T的析构函数被启用,以释放形式参数a,b,c的空间。
假定T是用户自定义数据类型且元素数据较多,使得复制和释放所用的时间则交大。
为节省传值参数在参数复制和释放空间时所需要的时间,使用引用参数表达式。
程序1-4 利用引用参数计算一个表达式
T abc(T &a, T &b, T &c) { return a + b * c; }
1.2.4 常量引用参数
C++提供了另一种参数传递模式-常量引用。该模式指明的引用参数不能被函数修改。
程序1-5 利用常量引用参数计算一个表达式
T abc(const T &a, const T &b,const T &c) { return a + b * c; }
用关键字const 来指明函数不可修改的引用参数。
可以设计一个更通用的版本。
程序1-6
template<class Ta,class Tb b,class Tc c> Ta abc(const Ta &a, const Tb &b,const Tc &c) { return a + b * c; }
1.2.5 返回值
一个函数可以返回一个值、一个引用或一个常量引用。前面的例子都是返回一个值。在这种情况下,返回的对象被复制到调用环境中。对于函数abc的所有版本来说,这中复制过程都是必要的。因为函数所计算出的表达式结果被存储在一个局部的临时变量中,当函数结束时,这个临时变量所占用的空间将被释放。为了不丢失这个值,在释放临时变量、局部变量以及传值参数的空间之前,要把这个值从临时变量复制到调用函数的环境中去。
给函数返回类型增加一个后缀&,我们便指定了一个引用返回。
函数头
T& mystery(int i, T&z);
定义了一个函数mystery,它返回的是类型T的一个引用。例如返回语句
return z;
这种返回形式不会把z的值复制到返回环境中。当函数结束时,形参i以及所有局部变量的空间都被释放。因为z仅仅是对一个实参的引用,所以它不受影响。
如果把关键字const加在函数头上,便得到const型引用返回
const T& mystery(int i, T&z);
const 引用返回与引用返回是类似的,不同之处在于,const引用返回在返回调用环境时,必须将值赋给const 常量。
1.2.6 重载函数
一个函数的签名是由这个函数的形参类型以及形参个数确定的。
在程序1-1中,函数abc的签名是(int ,int ,int )。C++可以定义两个或更多的同名函数,但是任何两个同名函数不能有同样的签名。
定义多个同名函数的机制称为函数重载。