定义:,嘛是引用?说的直白一点,引用就是对象的别名,这玩意最好的例子就是:假如你爹姓大,为了你以后闯荡江湖,你读书的时候要起个学名叫大狗剩,但你也有小名(某些文雅的人士叫乳名)叫狗剩,村里人都喊你狗剩,于是狗剩就是你的别名,你回家看看你的户口本,上面只写着大狗剩,此处就相当于内存,狗剩这个别名不占用空间,但是和大狗剩一样,都是指的你。
特点:先来看看跟指针的区别
1, 引用访问一个变量是直接访问,而指针是间接访问。
2,引用是一个变量的别名,本身不单独分配自己的内存空间,指针有自己的内存空间。
3,引用在开始的时候就绑定到了一个内存空间(开始必须赋初值),所以他只能是这个
内存空间的名字,而不能改成其他的。
(以下程序可能会因为word原因出现大小写问题比如“int”变成“Int”,知道就好了,敬请谅解)
(一)来一条一条看,先来看“别名”,别名的意思就是是一个东西,
int value;
int & refValue= value;
现在refValue就是value的一个引用,上面代码体现了两处,一是引用的定义,其次是定义引用的时候需要立即初始化,定义引用跟指针差不多,类型后面跟个&,不要跟取地址混了,
所谓立即初始化就是马上!,
所以你不能这样写:
int & refValue;
refValue= value;
另外与此沾边的是在任何情况下都不能使用空值的引用,你不能让他什么都不引啊,于是乎有些操蛋的家伙可能想到写这样的代码:
Int * ptrValue=NULL;
Int &refValue=(* ptrValue);
拖出去阉了吧,这样的代码应该避免,结果不确定,会很有害。
(二)引用是直接访问变量,指针是间接,所谓间接就是指针指向变量地址,需要使用“*”(解引用运算符)
说的明白一点就是直接用呗,跟原变量名一样直接用,不用添加额外的符号,但产生的是按引用的效果(比如按引用传值)
比如:
Int preValue=1;
Int realValue=2;
Void changeValue(int &a,int&b)
{
Int temp=a;
a=b;
b=a;
}
现在调用函数:changeValue(preValue,realValue);
注意preValue和realValue不需要加&,调用后preValue的值为2,realValue的值为1,这就是传说中的按引用传值,碉堡了。
(三)忠贞不二,引用只能被绑定一次,不能再引用别的变量,跟指针个这狗日的不一样,
比如对于指针,int value=1;
int fuckValue=2;
int *preValue=&value;
现在preValue指向value,
preValue=&fuckValue;
现在preValue指向fuckValue了,你执行*preValue=6;它改变的是fuckValue的值。
但对于引用‘
int value=1;
int fuckValue=2;
int & refValue= value;
现在refValue是value的引用。
假如你执行refValue= fuckValue;
此时refValue也不会变成fuckValue的引用,而只是会改变value的值为2
现在再来看看引用的另外两个特点
(一),如果一个函数返回的是一个引用类型,那么该函数可以被当作左值使用,当作左值的简单理解就是可以被赋值,比如
函数声明为:int & changeValue(int i);
在程序中:
Int value=1;
Int fuckValue=2;
changeValue(value)= fuckValue;
这样是正确的,至于changeValue的内部实现可能有多种情况,具体结果,要看return什么玩意了。
借花献佛,举个别人的例子:
int i;
int& f1(int&i)
{
return i;
}
f1(i)=3;这跟i=3效果是一样的。
(二)引用的转换
假如 float f;
int &rv=f;
加国是这种引用转换不能通过编译,但是并不是所有的转换都不能进行,比如基类就可以被作为派生类的引用(字面理解相当于将派生类转换成基类)
注意需满足两个条件:1,指定的基类是可访问的。2,转换是无二义性的
借花献佛举个例子:
class A
{
public:
int a;
};
class B:public A
{
public:
int b;
};
A Oa;
B Ob;
A& mm=Ob;
mm.a=3;
最后,别人总结了一下,我觉得挺好,拿来用了
1。对象和对象的引用在某种意义上是一个东西,访问对象和访问对象的引用其实访问的是同一块内存区。
2。使用对象和使用对象的引用在语法格式上是一样的。
3。引用必须初始化。
4。引用在初始化中被绑定到某个对象上后,将只能永远绑定这个对象。
5。基类类型的引用可以被绑定到该基类的派生类对象,只要基类和派生类满足上文提到的两个条件(1,指定的基类是可访问的。2,转换是无二义性的) 。这时,该引用其实是派生类对象中的基类子对象的引用。
6。用传递引用的方式给函数传递一个对象的引用时,只传递了该对象的地址,系统消耗较小。在函数体内访问 形参,实际是访问了这个作为实参的对象。
7。一个函数如果返回引用,那么函数调用表达式可以作为左值。