创建引用变量
引用变量,是已定义变量的别名。
c++中使用&符号来创建引用变量。
例如,将rodents定义为rats的别名,则可以使用以下代码:
1 2 int rats;int & rodents=rats;
此时,rodents和rats指向相同的值和地址。
可以通过下面的代码来测试:
1 2 3 4 5 6 7 8 9 int rats=101 ;int & rodents=rats;cout <<"rats=" <<rats<<",rodents=" <<rodents<<endl ;rodents++; cout <<"rats=" <<rats<<",rodents=" <<rodents<<endl ;rats=101 ,rodents=101 rats=102 ,rodents=102
从这方面来说,引用和指针很像,但是有几点不同:
引用必须在声明的时候初始化,而不能先声明,再初始化。
引用一旦与某个定义关联起来,就讲一直效忠于它,不再改变。
将引用作为函数参数
这种参数传递的方法叫按引用传递,不同于按值传递,按引用传递可以直接修改实参的值。
以下为一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iosteam> void add1 (int a) ;void add2 (int & a) ;int main () { using namespace std ; int a=1 ; add1(a); cout <<a<<endl ; add2(a); cout <<a<<endl ; } void add1 (int a) { a++; } void add2 (int & a) { a++ } 1 2
我们也可以选择不修改原始数据的值,可以在函数中使用const
下面这个例子用来计算参数的立方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iosteam> int cube1 (int a) ;int cube2 (int & a) ;int cube3 (const int & a) ;int main () { using namespace std ; int a=3 ; cout <<cube1(a)<<"=cube of " <<a<<endl ; a=3 ; cout <<cube2(a)<<"=cube of " <<a<<endl ; a=3 ; cout <<cube3(a)<<"=cube of " <<a<<endl ; } int cube1 (int an) { an*=an*an; return an; } int cube2 (int & an) { an*=an*an; return an; } int cube3 (const int & an) { an*=an*an; return an; } 27 =cube of 3 27 =cube of 27 27 =cube of 3
使用const修饰时,main函数中的值没有发生改变。
在上面的例子中,cube1和cube3实现的功能类似,为什么还要多此一举使用引用类型呢?
这是因为,在按值传递的函数中,编译器会自动生成一个形参的副本,也就是一个临时变量,来存储实参的值。当我们需要传递的参数内容较大时,会造成一定的内存浪费。
使用引用传递,则可以直接将实参的地址传递到函数中,不需要生产临时变量,节省空间和时间。
在结构体和类对象中,引用就显得十分必要。
将引用用于结构
使用结构引用参数的方式与使用基本变量相同,只需在声明结构参数的时候使用引用运算符&即可。
假设有如下结构体定义:
1 2 3 4 5 6 7 8 9 struct person { string name; int age; } void show (person & p1) ;void show (const person & p1) ;
下面用一个例子来说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std ;struct person { string name; int age; } person & older (const person & p1,const person & p2) ;void show (const person & p3) ;int main () { person father={'James',40}; person son={'Simon',18}; show(older(father,son)); } person & older (const person & p1,const person &p2) { if (p1.age>p2.age) return p1; else return p2; } void show (const person & p3) { cout <<"name:" <<p3.name<<",age:" <<p3.age<<endl ; } name:James,ages:40
此程序是找出person中年龄较大的那一个。
关于语句show(older(father,son));
,有下面的解释。
首先,father作为第一个参数传递给了older(),这意味着,在older()中,p1指向的是father。
同理,son作为第二个参数传递给了older(),在older()中,p2指向的是son。
将两者的age属性进行比较后,将年龄较大的person结构体的引用返回,在此次的例子中,返回的是father,也就是说,返回的是最初传进来 的father对象。
接下来,将older()的返回值作为参数传递给了show(),这意味着将father传递给了show()。
为什么要返回引用类型?
假设有这么一条语句:
如果older返回的是一个值,而不是引用,则编译器会把整个结构体复制到一个临时变量,再将这个临时变量拷贝复制给p3。但在返回值是引用时,将直接把father复制到p3,其效率更高。
还有一点要注意:
上述代码中,show函数的参数使用了const修饰,但older的返回值类型并没有const修饰,但程序依旧可以运行不报错,这是因为,在c++中,可以将一个非const变量赋给const类型,但不可以把一个const变量赋给非const类型。