跟着侯捷老师学C++☛引用

214 阅读2分钟

栗子

  • 第一次
int x = 0;
int* p = &x;  // p is a pointer to X
int& r = x;  // r is a reference to X
int x2 = 5;

对于int x = 0,x是一个整数变量,内存分配了一块区域给x,大小为4字节,假设是0Xffff1。然后x的值是0.

对于int* p = &x;,p是一个指针变量,内存分配了一块区域给p,大小为4字节(32位电脑上),假设是0Xffff2。然后它的初值指向x的地址,也就是p的值是0Xffff1

对于int& r = x;,r是一个引用变量,内存分配了一块区域给r。r是引用的x,可以理解成r代表了x,他俩是一个东西。由于x是整数内存为4字节,所以r分配的内存大小也为4字节,假设是0Xffff3。r的值也就是x的值,是0。

引用一定要有初值,且设完后不能改变!否则编译器报错
sizeof(r) == sizeof(x)
&x == &r 特别注意,虽然r有另外分配内存,但&r是和&x相等的,都是0Xffff1。

对于int x2 = 5,x2是一个整数变量,内存分配了一块区域给x2,大小为4字节,假设是0Xffff4。然后x的值是5.

  • 第二次

继续看下面代码

r = x2;
int& r2 = r;

对于r = x2;,由于r是个引用,且它的初值已经赋了x。我们又强调了引用定义后不能更改。所以这句话的意思并不是把r的引用变成了x2,而是把x2的值赋给r。由于r是x的引用,所以此时r=5x=5。我们可以理解成,引用就是一个别名!一定引用后就不能重新引用了!

对于int& r2 = r;,r2是一个引用变量,r2代表r,r代表了x,所以它们仨是同一个东西。同时,内存也给r2分配了一块区域,大小为4字节。此时r2的值是5.

image.png

常见用途

reference通常不用于声明变量,而用于参数类型和返回类型的描述

void func1(Cls* pobj) { pobj->xxx(); }  // 被调用端写法不同,不好
void func2(Cls obj)   { obj.xxx(); }  // 被调用端写法相同,很好
void func3(Cls& obj)  { obj.xxx(); }  // 被调用端写法相同,很好
...
Cls obj;
func1(&obj);   // 接口不同,困扰
func2(obj);  // 调用接口相同
func3(obj);  // 调用接口相同

以下被视为“same signature”,所以不能共存

double imag(const double& im) {...}
double imag(const double  im) {...}  // ambiguity