《Essential C++》读书笔记 之 面向过程编程风格
2014-06-18
2.2 调用(invoking)一个函数
2.2.1 Pass by Reference语义
reference扮演这外界与对象之间的一个间接号码牌的角色。只要在性别名称和reference名称之间插入&符号,便声明了一个reference:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int ival=1024; //对象,型别为int 7 int *pi=&ival; //pointer(指针),指向一个int对象 8 int &rval=ival; //reference(化身),代表一个int对象 9 10 //这里不是令rval改为代表jval对象,而是将jval赋值给rval所代表的对象(也就是ival)。 11 int jval=4096; 12 rval=jval; 13 14 //这里不是令pi指向rval对象,而是将ival(此为rval所代表之对象)的地址赋给pi 15 pi=&rval; 16 17 return 0; 18 }
重点是:面对reference的所有操作都像面对“reference所代表的对象”所进行的操作一样。当我们以reference作为函数参数时,情况是一样的,如下代码所示:
1 #include <iostream> 2 void swap(int &, int &); 3 4 int main() 5 { 6 int v1=1; 7 int v2=2; 8 swap(v1,v2); 9 10 v1; 11 v2; 12 13 return 0; 14 } 15 16 void swap(int &val1, int &val2) 17 { 18 int temp=val1; 19 val1=val2; 20 val2=temp; 21 }
运行结果如下图所示:
将参数声明为reference的理由有两个:
- 希望直接对所传入的对象进行修改;
- 为了降低复制大型对象的负担。
如果我们愿意,也可以将参数以pointer形式传递。这和以reference传递的效用相同:传递的是对象地址,而不是整个对象的复制品。唯一的差别是他们的用法不同。如下代码所示:
1 #include <iostream> 2 3 void swap(int *,int *); 4 5 int main() 6 { 7 int v1=1; 8 int v2=2; 9 swap(&v1,&v2); 10 11 v1; 12 v2; 13 14 return 0; 15 } 16 17 18 void swap(int *val1, int *val2) 19 { 20 int temp=*val1; 21 *val1=*val2; 22 *val2=temp; 23 }
但如果swap方法改成如下,变量v1,v2不会调换:
1 void swap(int *val1, int *val2) 2 { 3 int *temp=val1; 4 val1=val2; 5 val2=temp; 6 }
因为上述方法只是更改了指针本身的地址,如下图: