6.2 参数传递
每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化。
- 当形参是引用类型时,对应的实参被引用传递(passed by reference)或者函数被传引用调用(called by reference)。
- 当实参的值被拷贝给形参时,形参和实参是两个相互独立的对象,实参被值传递(passed by value)或者函数被传值调用(called by value)。
6.2.1 传值参数
当初始化一个非引用类型的变量时,初始值被拷贝给变量。此时,对变量的改动不会影响初始值。
传值参数的机理也是如此,函数对形参所做的所有操作都不会影响实参。
指针形参
指针的行为和其他非引用类型一样。当执行指针拷贝操作时,拷贝的是指针的值。拷贝之后,两个指针是不同的指针。因为指针可以间接地访问它所指的对象,所以通过指针可以修改它所指对象的值。
int n = 0, i = 42;
int *p = &n, *q = &i; // p 指向 n,q 指向 i
*p = 42; // n 的值改变:p 不变
p = q; // p 现在指向了 i;但是 i 和 n 的值都不变
指针形参的行为与之类似
// 该函数接受一个指针,然后将指针所指的值都置为 0
void reset(int *ip)
{
*ip = 0; // 改变了指针 ip 所值对象的值
ip = 0; // 只改变了 ip 的局部拷贝,实参未被改变
}
int i = 42;
reset(&i); // 只改变了 i 的值而非 i 的地址
cout << i << endl; // 输出 i = 0;
在 C 中,使用指针类型的形参访问函数外部的对象;
在 C++中,使用引用类型的形参替代指针。
6.2.2 传引用参数
使用引用形参,允许函数改变一个或多个实参的值。
使用引用避免拷贝
拷贝大的类类型对象或者容器对象比较低效,有的类类型不支持拷贝操作。当某种类型不支持拷贝操作时,函数只能通过引用参数访问该类类型对象。
// 比较两个 string 对象的长度
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
如果函数无须改变引用形参的值,将其声明为常量引用。
使用引用形参返回额外信息
一个函数只能返回一个值,但引用形参为一次返回多个结果提供了有效的途径。
// 返回 s 中 c 第一次出现的位置索引
// 引用形参 occurs 负责统计 c 出现的次数
string::size_type find_char(const string &s, char c, string::size_type occurs)
{
auto ret = s.size(); // 第一次出现的位置
occurs = 0; // 设置表示出现次数的形参的值
for (decltype