转自C++中&的用法总结 - 百度文库
声明引用
int a = 3;
int& b = a; //b是a的引用,a,b是同一变量
b = 4; //这时候a也变为4
int c = 2;
b = c; //将c赋值给a或者b,而不是把b作为c的引用,引用一旦被声明同时被初始化,引用对象不可更改
引用的实质是指针的简化运用版,上面的代码等价为
int a = 3;
int* const b = &a; //常指针,b的位置不能更改,相当于引用不能更改自身引用对象 *b = 4;
所以引用省去了声明时的取地址操作和对变量内存地址引用时的解引用操作,而且引用不能随意被更改,站在指针的角度上说,引用的意义等价于一个常指针,也就是不能改变自己指向位置的指针。
引用在作为参数传递的时候,传递的是实参本身,C++里面类设计经常要传递整个类作为参数,但如果在不必要的时候使用传统的按值传递,效率损失可见一斑:
class foo {
public:
...
int a;
double b;
string c;
};
void bar(foo f)
{
//输出abc
}
比如这个函数bar,传参的时候是按值传递,也就是实参的所有数据被重新复制到参数f里,构造了一个新对象f,它只是输出参数f的abc成员,所以必要重新构造一个临时对象f,这样造成了效率的损失,解决方法有2种:
void bar1(foo* f)
{
cout<<f->a<<f->b<<f->c;
}
var bar2(foo& f)
{
cout<<f.a<<f.b<<f.c;
}
这2种方式的运作机制是相同的,但是后者要更简洁和优美一些,特别是在操作多层间接指针的函数里面,直接使用指针的话,过多取地址&和解引用*容易造成代码混乱,降低可读性。
friend Complex operator +(Complex&, Complex&);
假如不写"&"的话,其影响有两个。
引用“& " 的用法与指针的用法
void swap(int& p1, int& p2)
{
undefined
int p;
p = p1;
p1 = p2;
p2 = p;
}
为在程序中调用该函数,则相应的主调函数的调用点处,直接以变量作为实参进行调用即可,而不需要实参变量有任何的特殊要求。如:对应上面定义的swap函数,相应的主调函数可写为:
main()
{
int a,b;
cin>>a>>b; //输入a,b两变量的值
swap(a,b); //直接以变量a和b作为实参调用swap函数
cout<<a<<" "<<b; //输出结果
}
上述程序运行时,如果输入数据10 20并回车后,则输出结果为20 10。
但是我们可能碰到例如
intStackEmpty(SqStack s)
{
if(s.top == s.base)
return TRUE;
return FALSE;
}
int Push(SqStack& s, SElemType e)
{
if(s.top - s.top>= s.stacksize)
{
s.base=(SElemType*)realloc(s.base,(s.stacksize + STACKINCREMENT)*
sizeof(SElemType));
if(!s.base)
exit(OVERFLOW);
s.top = s.base + s.stacksize;
s.stacksize += STACKINCREMENT;
}
*s.top++ = e;
return TRUE;
}
int Pop(SqStack& s, SElemType& e)
{
if(s.top == s.base)
return FALSE;
e=*--s.top;
return TRUE;
}
在堆栈操作中,有的不用&,有的要用&,什么时候使用引用 ?