引用:reference 已存在变量的别名。 使用引用的必要性:资源使用 思想层:受限制的指针。 语法层:T a; T &p=a; 编译器:给你做了保证,一定是经过初始化的指针 汇编层:和指针一样。 在汇编层,指针和引用是完全一样的。 引用是一个语法糖,T a; T &p=a; 等价于 T *const p = &a int x=0
00676664 mov dword ptr [x],0
int &a = x
0067666B lea eax,[x]
0067666E mov dword ptr [a],eax
a = 1
00676671 mov eax,dword ptr [a]
00676674 mov dword ptr [eax],1
int *p = &x
0067667A lea eax,[x]
0067667D mov dword ptr [p],eax
*p = 2
00676680 mov eax,dword ptr [p]
00676683 mov dword ptr [eax],2
int *const p2 = &x
00676689 lea eax,[x]
0067668C mov dword ptr [p2],eax
*p2 = 3
0067668F mov eax,dword ptr [p2]
00676692 mov dword ptr [eax],3
引用的情况: int a = 1;
const int b = 1;
int &ref1 = a;
int &ref2 = 1;
const int &ref3 = b;
const int &ref4 = 1;
Q:唯独int &ref2 = 1;//ERROR? A:C++的早期这种语法是被允许的,但是在函数调用传参数时,会给程序员带来误解,于是后面就禁止了这种语法。 引用规则的特例:const引用 void f(int &i){}
void f(const int &i){}
int main(){
int i = 1;
f(i);
f(2);
return 0;
}
void f(int &i){}
int main(){
int i = 1;
f(i);
f(2);
return 0;
}
void f(const int &i){}
int main(){
int i = 1;
f(i);
f(2);
return 0;
}
C++语言中就有了新的参数传递方式:引用传递 void f(T &p) 。实质也是传值。 自定义类型最好用引用传递,可以避免不必要的构造函数和析构函数的调用。 内置类型建议用值传递,自定义类型建议用引用传递,内置类型,值传递会比按引用传递更高效。 解释见:这里 利用引用交换两个数字 #include <iostream>
#include <stdlib.h>
using namespace std;
void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}
int main(){
int a = 3;
int b = 4;
swap(a, b);
cout << "a=" << a<<" " << "b=" << b << endl;
return 0;
}
引用的级数 只能一级,引用的对象必须是一个已存在的地址。引用变量本身的地址,外界不能访问。 References are not objects; they do not necessarily occupy storage, Because references are not objects, there are no arrays of references, no pointers to references, and no references to references。
int& a[3]; // ERROR
int&* p; // ERROR
int& &r; // ERROR 引用和指针叠加
int a; int *p = &a; int *&r = p; //OK 使用引用的场景: - 给函数传递可变参数
- 给函数传递大型对象
- 引用函数返回值;
Q:引用能实现的基本上指针都可以实现,那为什么C++还需要引入引用呢? A:最初主要是为了支持运算符重载。 c = a + b是可以接受的写法,而c = &a + &b 就不是很方便而且有歧义了。 写法上的方便是要第一考虑的。 Q:C++引入了引用,那为什么C++不和Java一样让指针对使用者不可见呢? A:历史原因。为了兼容C语言。程序员是自由的。 Q:C++为什么选择&作为引用的标识符? A:需要用一个符号告诉编译器,传的是引用。&在C语言中是取地址的作用,于是就选择了它。 Q:this为什么是指针类型,而不是引用类型? A:历史原因。this诞生早于引用。某种意义上来讲,this应该被设计为引用类型。 Q:Why is "this" not a reference? A:Because "this" was introduced into C++ (really into C with Classes) before references were added. Also, I chose "this" to follow Simula usage, rather than the (later) Smalltalk use of "self". Q:拷贝构造函数参数一定是引用,不然编译通不过,为什么? A:因为在入参的过程中,如果不是引用,会首先进行一次值拷贝;而要实现的就是拷贝构造,就会造成不断的递归最后爆炸。 Q:引用是受限制的指针,哪里受限制了? A:引用变量本身的地址外界不可获得,当然编译器是可以的。 Q:引用变量是否占有内存空间? A:引用可以不占用,也可以占有。语法规定对引用变量的操作都是对被引用对象的操作。 struct S {
int a;
int &b;
};
int x = 123;
S s(123,x);
sizeof(S)=?//32位环境等于8 non-const引用的汇编视角
 const引用的汇编视角
 说明:const引用变量绑定没有地址的对象时,会生成一个临时变量/匿名对象来中转。
|