<ZT>Blog: http://zhangjunhd.blog.51cto.com/
1.变量的引用
对一个数据可以使用引用(reference),引用的作用是为变量起一个别名。
|
int a;//定义整型变量a
int &b=a;//声明b是a的引用
|
上面语句声明b是a的引用,即b是a的别名。&是引用声明符(不是取地址运算符)。将b声明为a的引用,不需要为b另外开辟内存单元。b和a占内存中的同一个存储单元,它们具有同一地址。
在声明一个引用时,必须同时使之初始化,即声明它代表哪一个变量。在声明变量b是变量a的引用后,在它们所在函数执行期间,该引用类型变量b始终与其代表的变量a相联系,不能再作为其他变量的引用。
|
int a1,a2;
int &b=a1;//ok
&b=a2;error: ISO C++ forbids cast to
non-reference type used as lvalue
|
引用不是一种独立的数据结构,必须指定其代表某一类型的实体(如变量、对象),不能定义引用数组和指向引用的指针。
2.引用的使用
|
int
}
|
结果:
i_one=6,&i_one=0x22ff74
r_int=6,&r_int=0x22ff74
i_one=9,&i_one=0x22ff74
i_two=9,&i_two=0x22ff6c
r_int=9,&r_int=0x22ff74
可以发现[1]引用r_int与它的本体变量i_one占用的是用一个地址;[2]当借助引用改变变量的值时,其本体变量的值也随之改变。
3.指针变量的引用
可以有指针变量的引用,
|
int
}
|
结果:
r=0x22ff60,p=0x22ff60
r->1,p->1
r=0x22ff54,p=0x22ff54
r->9,p->9
这里通过引用改变了指针变量的指向。同样可以将引用指向void指针。
|
int
}
|
结果:
p->1,r->1
但是,不能对void进行引用;不能建立数组的引用;引用本身不是类型,所以没有引用的引用;也没有引用的指针。
用引用方式传递函数参数,其“效果”与使用指针的“效果”是一样的。
4.使用引用返回值
|
const float pi=3.14;
float f;
int
}
float f1(float r){
}
float& f2(float
r){
}
|
[1]函数f1()返回一个一般的float变量;函数f2()返回一个float变量的引用;main()中1,2,3,4“效果”相同,得到的值是78.5。
[2]①中会将全局变量f的值78.5赋给一个临时变量temp(由编译器隐式的建立),再由临时变量赋给变量a。
[3]②错误的原因是不能对一个临时变量temp进行引用。
[4]③在返回值时并没有隐式的建立临时变量temp,而是直接将全局变量f返回给主函数。
[5]④在主函数中都不使用定义变量,而是直接使用全局变量的引用,这种方式是全部4种中最节省内存空间的。但必须注意它所引用的变量的有效期,此处全局变量f的有效期肯定长于引用d,所以是安全的。
如果将一个局部变量的引用返回,则会出现警告,
|
const float pi=3.14;
int
}
float& f2(float
r){
}
|
5.函数调用作为左值(返回一个引用时)
通过上面的示例发现,只要避免将局部栈中变量的地址返回(即返回一个临时的引用),则可以返回一个引用使得函数调用表达式成为左值。
下面是一个判断奇偶的函数,
|
int
arr[]={1,2,3,4,5,6,7,8,9};
int&
check(int*,int&,int&);
int
}
int& check(int*p,int
&odd,int &even){
}
|
check()函数返回的是一个引用,如果是奇数则奇数引用值加1,否则偶数引用值加1。这里直接返回的是形参引用,所以有效的避免了返回临时引用的问题。函数的自加操作其实就是整型变量t_odd和t_even的自加操作。
6.操作堆中变量的引用
|
const double PI=3.14;
int circle_area();
int
}
int circle_area(){
}
|
函数circle_area()中指针p接受new返回的堆空间地址,必须进行检验,看是否内存分配成功;声明指针变量p的引用r。返回堆空间有两种方式,方式一delete
p;方式二delete &r。
插入表情