C++引用原理剖析

在理解引用概念前,先回顾一下变量名。

变量名实质就是一段连续存储空间的别名(内部有自己的编号),是一个标号(门牌号),程序需要通过变量来申请并命名内存空间(编译器建立与内存地址的联系)?

那么问题来了,一段连续的内存空间只能取一个别名吗?显然不是,引用的概念诞生了。

在C++中新增了引用的概念,引用是一个已定义变量的别名。其语法是  Type& name = var; 例如:

int a = 10; //c编译器分配4个字节内存。a内存空间的别名

int&b = a;  //b就是a的别名。。。

思考1:如何使用引用?引用的价值如何体现?

引用做函数参数,回想经典的交换两个变量的值,形参和指针做函数参数传递的效果。地址传递和值传递的区别,引用不就是地址的别名吗?这样就可以有效的解决这个问题了。

引用做函数参数时需要区别普通引用。普通引用声明时必须要初始化。而引用做函数参数不需要初始化。从例子中来理解为什么可以这样。

struct Teacher

{        charname[64];

         intage ;

};

void printfT(Teacher *pT)

{         cout<<pT->age<<endl;

}

void printfT2(Teacher &pT)

{         //cout<<pT.age<<endl;

         pT.age= 33;

}

void printfT3(Teacher pT)

{

         cout<<pT.age<<endl;

         pT.age= 45; //只会修改pT变量 ,不会修改t1变量

}

void main()

{       Teachert1;

         t1.age= 35;

         printfT(&t1);

         printfT2(t1);//pT是t1的别名

         printf("t1.age:%d\n", t1.age); //33

         printfT3(t1);// pT是形参 ,t1 copy一份数据给pT     //---> pT = t1

         printf("t1.age:%d\n", t1.age); //35

         cout<<"hello..."<<endl;   

         system("pause");

         return;

}

ok,我们知道了如何使用引用了,那么引用的意义和价值又是什么呢?我们继续讨论。

引用的意义:既然引用作为其他变量的别名而存在,那么在很多场合是不是可以代替指针呢,因而也具有更好的可读性和实用性。这就是引用存在的意义。


引用看起来非常简单易理解,不就是给一个变量重新取一个名字吗?需要使用变量的时候就派它代替源变量去处理,并具有一样的处理权利。引用给程序员带来了非常便捷的处理方式,那么C++编译器又是如何提供这种处理机制呢?下面我们进入到引用的本质探讨。

2. 引用的本质思考

    int a = 10;

    int &b =a;     //b是a的别名,请问c++编译器后面做了什么工作?

    printf("sizeof(b)%d\n", sizeof(b)); 普通引用有自己的空间吗?

(深入理解的关键)引用在C++中内部实现是一个常指针。Type& name    <-->     Type*const name

这么做事为了实用性做出的细节隐藏

void func(int &a)          void func( int *const a)

 { a=5;                                    {  *a =5;

}                                                  }

请试着思考:对比间接赋值成立的三个条件:

1. 定义两个变量(一个实参,一个形参)

2. 建立关联,实参去地址传递给形参

3. *p形参去间接修改实参的值。

在引用的实现上,将后两步合为一步完成,不需要通过去地址去修改实参的值。传递过来的就是实参地址,直接通过别名修改即可。


似乎现在已经对引用有了更深刻的理解,接下来我们进入到一个新的认识高度:常引用

常引用就是const修饰的引用

请思考  cost int &a = b PK const int &a = 10;

这就是常引用初始化的两种形式:左边用变量,右边用常量。

左边是常见的方式应该很好理解,右边请思考去掉关键字const会怎样?即 int &a=10; 显然是不行的,引用是对变量去别名,字面常量10 是没有内存空间的,不能做引用。但是加长const之后,编译器就会为常量分配内存空间,并将引用名作为该内存空间的别名。最后总结常引用使得变量具有只读属性(可以通过指针修改)引用无法修改(别名)。

至此,引用的基本类型已经分析结束。




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值