64,687
社区成员
发帖
与我相关
我的任务
分享
int n = 10,m=11; //一般变量定义(非引用类型)
int &ref = n; //C++引用定义,引用必须初始化,初始化后被引用的对象,就会永远保持不变。
//C++中,ref只能引用n,不会再改为引用别的变量,比如m;
ref =m; //就是 n = m; 不是改为引用m;
// 引用不支持一般意义的赋值运算,如何理解?
//就是指的这种情况吧,把如果ref是指针,ref= &m;就会指向新对象了;
//不过这种解释很晦涩,更不好理解了。
//
//这里ref 没有更换引用的目标,还是引用的n,这个赋值操作和 n=m;效果一致
//其实就是 *(int *)&n =m;的意思;
引用的实现,就像下面的代码差不多;
//int n=10,m=11;
//int &ref = n;<==> int *const pref = &n; //ref 是 n的别名,就是 n的另一个名字
//ref =m; <==> *pref =m; <==> n=m;
//ref++; <==> (*pref)++; <==> n++;
//m =ref; <==> m = *pref; <==> m = n;
//ref +=m; <==> (*pref)+ m;
//下面是 引用的实现和概念的区别。
// 实现上,就是个指针常量,指针的值是被引用变量的地址;概念上是别名,是另一个变量的代表。
//&ref<==> pref 实现上,保存了被引用变量的地址<==> &n; 概念上,因为是同一个对象,所以地址相同。
//ref<==> *pref 实现上,引用值就是地址中的值<==> n; 概念上,因为是同一个对象,所以值也相同。
//概念上,语法上,理解引用,以及引用初始化,赋值,取地址。
int n=10,m=11;
int &ref =n; //ref:我就是n; n:我叫n,有时别人也叫我 ref,ref是我的外号(别名);
ref = m;//ref:我就是n,给我赋值就是给n 赋值; n:ref 就是我呀,给ref赋值就是 给我赋值呀。
ref++;//ref:我就是n,我自增就是n自增; n:ref 就是我呀,ref自增就是我自增呀。
m =ref;//ref:我就是n,我的值赋值给m,就是n的值赋值给m;
//n:ref 就是我呀,ref的值赋值给m,就是我的值赋值给m呀;
int *p =&ref;<==> int *p=&n;//ref:我就是n,我的地址就是n的地址;
//n:ref 就是我呀,ref的地址,就是我的地址;
PS:
这里出现了一个问题,引用 ref 这个变量的实现,本身也需要一个地址;
但是这个地址对于我们是透明的,不是可以用正常的语法手段获取的。
我们只能够获取,这个地址里面储存的数据,即被引用的对象的地址。
这也是C++刻意这样做的,同时也是必须这样做的。
对于C++的引用,用如下语句初始化后:
int &ref =n;
下面的恒等式,永远成立,直到其中一个结束生命周期为止:
&ref ==&n;
ref == n;
下面的例子,可以演示引用,取地址和取值,以及存储引用的实际地址之间的异同。
#include<iostream>
using namespace std;
struct ref_struct{
ref_struct(int &n):ref(n){};//有兴趣的话,也可以在这里输出.
public:
int &ref;
}
int main()
{
int n=10;
ref_struct r(n);
cout<<"存储引用的地址="<<&r<<",引用的地址=" << &r.ref<<",被引用对象的地址"&n<<endl;
cout<<"引用的值="<<r.ref<<",被引用对象的值=" <<n<<endl;
return 0;
}
int a, b;
int &ri = a; //ri 引用a
ri = b;//ri不会引用b,而是把b的值赋值给a
int * pi = &a;//pi指向a
* pi = b;//这句是给a赋值
pi = &b;//pi改为指向b
把引用看成特殊的指针,然后用指针的观点去待引用,才有这么一种说法,因为对引用的赋值与指针完全不同……
这样反而把问题弄复杂了。引用不但“不支持一般意义的赋值运算”,而且还不支持一般意义的取地址运算”呢……
事实上,如果不把引用与指针联系起来,那么引用的这些行为很正常。引用型变量就是给变量起一个别名,对它赋值当然就等同于对原变量赋值,对它取地址也理所应当地取到原变量的地址。引用型参数就是“变量参数”,让参数成为实参变量的别名,函数内部可以通过它来改变被引用的变量。