引用:就是对某一变量(或对象)取一个别名,对变量的引用 的操作与对变量本身直接操作完全一样。
引用的声明:类型标识符 &引用名=目标变量名;
如下:定义变量a的引用aa,即别名。
int a = 5;
int &aa=a; //以后对aa的操作运算,就直接对变量a本身起作用
(1)&在此不是取地址运算符,而是起标识作用。&aa —是一个整体。
(2)类型标识符是指目标变量的类型。
(3)声明引用时,必须同时对其进行初始化;类似于const常量初始化。
(4)引用声明完毕后,相当于目标变量有两个名称即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名,也就是说一旦声明一个引用绑定到每个变量或对象,就不能再作其他变量的引用,即引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量,具有“终身制”。
(5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。所以:对引用求地址,就是对目标变量求地址。&aa与&a相等。引用在定义上是说引用不占据任何内存空间,但是编译器在一般将其实现为const指针,即指向位置不可变的指针,所以引用实际上与一般指针同样占用内存。
(6)不能建立引用数组,因为数组是一个由若干个元素所组成的集合,所以无法建立一个由引用组成的集合,但是可以建立数组的引用。引用不可以作数组中的元素。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。另外数组名本质是一个指针。
(7)使用对象和使用对象的引用,在语法格式上是一样的。对象和对象的引用在某种意义上是一个东西,访问对象和访问对象的引用其实访问的是同一块内存区。
(8)基类类型的引用可以被绑定到该基类的派生类对象,只要基类和派生类满足两个条件。这时,该引用其实是派生类对象中的基类子对象的引用。
(9)引用常见的使用用途:作为函数的参数[最常用]、函数的返回值,常引用。
a.常引用声明方式:const 类型标识符 &引用名 = 目标变量名;
b.用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。
c.引用型参数如果为const,则函数体不能对引用型参数修改目标变量。
· void TestReference1()
· {
· int d1 = 4;
· const int & d2 = d1;
· d1 = 5; //d1改变,d2的值也会改变。
· //d2 = 6;//不能给常量(不能被修改的量)赋值。 常引用不能对引用型参数修改目标变量。
·
· const int d3 = 1;
· const int & d4 = d3;
· //int&d5 = d3;
· const int & d6 = 5;//常量具有常量性,只有常引用可以引用常量
· }
函数最多只能有一个返回值。那如果需要一个函数返回多个类型的值怎么办?解决方案之一就是:将待返回的都定义为全局变量,通过引用参数传入函数,数据操作之后,那些待返回的值就改变了,但会造成全局变量混杂。使用引用作为函数的返回值,函数执行完,返回的是引用,可以引向的是很大的数据内存区,可以更有效解决。
引用作为函数的返回值,函数定义时要按以下格式:
类型标识符 &函数名 (形参列表及类型说明)
{ 函数体 }
说明:
(1)以引用返回函数值,定义函数时需要在函数名前加&
(2)用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。
(3)如果一个函数返回的是一个引用类型,那么该函数可以被当作左值使用。什么是左值搞不懂先别管,只需了解:如果一个对象或表达式可以放在赋值号的左边,那么这个对象和表达式就叫左值。
#include
float temp;//定义全局变量temp
float fn1(float r);//声明函数fn1
float &fn2(float r);//声明函数fn2 r
float fn1(float r){//定义函数fn1,它以返回值的方法返回函数值
temp=(float)(r*r*3.14);
return temp;
}
float &fn2(float r){//定义函数fn2,它以引用方式返回函数值
temp=(float)(r*r*3.14);
return temp;
}
void main(){
float a=fn1(10.0);//第1种情况,系统生成要返回值的副本(即临时变量)
// float &b=fn1(10.0); //第2种情况,可能会出错(不同 C++系统有不同规定)
/*
编译错误:cannot convert from ‘float’ to ‘float &’
A reference that is not to ‘const’ cannot be bound to a non-lvalue
*/
//不能从被调函数中返回一个临时变量或局部变量的引用
float c=fn2(10.0);//第3种情况,系统不生成返回值的副本
//可以从被调函数中返回一个全局变量的引用
float &d=fn2(10.0); //第4种情况,系统不生成返回值的副本