c++引用变量详解

创建引用变量

引用变量,是已定义变量的别名。

c++中使用&符号来创建引用变量。

例如,将rodents定义为rats的别名,则可以使用以下代码:

int rats;
int & rodents=rats;

此时,rodents和rats指向相同的值和地址。

可以通过下面的代码来测试:

int rats=101;
int & rodents=rats;
cout<<"rats="<<rats<<",rodents="<<rodents<<endl;
rodents++;
cout<<"rats="<<rats<<",rodents="<<rodents<<endl;

//output
rats=101,rodents=101
rats=102,rodents=102

从这方面来说,引用和指针很像,但是有几点不同:

  • 引用必须在声明的时候初始化,而不能先声明,再初始化。
  • 引用一旦与某个定义关联起来,就讲一直效忠于它,不再改变。

将引用作为函数参数

这种参数传递的方法叫按引用传递,不同于按值传递,按引用传递可以直接修改实参的值。

以下为一个例子:

#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++
}

//output
1
2

我们也可以选择不修改原始数据的值,可以在函数中使用const

下面这个例子用来计算参数的立方:

#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;
}

//output
27=cube of 3
27=cube of 27
27=cube of 3

使用const修饰时,main函数中的值没有发生改变。

在上面的例子中,cube1和cube3实现的功能类似,为什么还要多此一举使用引用类型呢?

这是因为,在按值传递的函数中,编译器会自动生成一个形参的副本,也就是一个临时变量,来存储实参的值。当我们需要传递的参数内容较大时,会造成一定的内存浪费。

使用引用传递,则可以直接将实参的地址传递到函数中,不需要生产临时变量,节省空间和时间。

在结构体和类对象中,引用就显得十分必要。

将引用用于结构

使用结构引用参数的方式与使用基本变量相同,只需在声明结构参数的时候使用引用运算符&即可。

假设有如下结构体定义:

struct person{
  string name;
  int age;
}

//函数原型如下
void show(person & p1);
//如果不希望函数修改传入的结构,可以使用const
void show(const person & p1);

下面用一个例子来说明:

#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;
}

//output
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()。

为什么要返回引用类型?

假设有这么一条语句:

p3=older(father,son);

如果older返回的是一个值,而不是引用,则编译器会把整个结构体复制到一个临时变量,再将这个临时变量拷贝复制给p3。但在返回值是引用时,将直接把father复制到p3,其效率更高。

还有一点要注意:

上述代码中,show函数的参数使用了const修饰,但older的返回值类型并没有const修饰,但程序依旧可以运行不报错,这是因为,在c++中,可以将一个非const变量赋给const类型,但不可以把一个const变量赋给非const类型。

参考资料:c++ primer plus 第六版 中文版

上一篇:android 数据库的升级与降级解决方案


下一篇:csp 数据中心 python