一文带你详细了解C++的引用

前言

在C的世界里要写一个函数对两个数进行交换,需要通过指针,进行传址。但在C++的世界里新增了一种新的类型来完成上述操作,这种类型就是引用。

相关的代码如下:

#include <iostream>
using namespace std;

void mySwap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int a = 10, b = 20; 
    cout << "a=" << a << " b=" << b << endl;
    mySwap(a, b); 
    cout << "a=" << a << " b=" << b << endl;
    return 0;
}

可以看到我们直接在调用mySwap函数时,用法跟传值一样,将实参a,b传递给了mySwap函数,不需要类似传址一样,加上取地址符&。

定义

引用为对象起了另外一个名字,引用并非对象。如何定义一个引用类型呢?我们只需要在变量前面

加上&。

使用引用需要注意以下几点:

1、定义引用时需要跟一个具体的对象绑定在一起,什么是具体的对象,我们可以简单的理解成为,在内存中有一块真正的内存去存储这个对象。因此引用必须初始化。如:

int &refVal;  //错误,无法令引用重新绑定到另外一个对象,需要初始化
---------------------------------------
int a = 10;
int &refVal = a; //正确
---------------------------------------
int &refVal = 20; //错误,并不是一个对象

2、引用本身不是对象,因此引用不占用内存空间(至少在编译器给我们看到的现象是这样的

3、引用的类型必须要和与之绑定的对象类型严格匹配

  • 常量引用除外
  • 基类引用派生类对象除外

进一步探究引用底层实现

示例代码如下:

#include <iostream>
using namespace std;

int main() {
    int a = 10; 
    int  &refVal = a;
    double dval = 3.456;
    const int &ri = dval;
    return 0;
}

对上述代码进行编译,并使用gdb进行调试(关于gdb的一些使用操作可以参考http://t.csdnimg.cn/vXsEn):

我们从7c1这条汇编指令开始分析,将10存放在了栈空间$rbp-0x28处,即变量a的地址是$rbp-0x28(ffdf68

继续单步调试代码:

可以看到int  &refVal = a;这条语句的汇编指令是7c87cc两条。这两条指令含义是将变量a的地址存放在了栈空间$rbp-0x20处:

可以看到编译器其实在底层实现上,给引用refVal分配了内存,内存地址是ffdf70,在底层实现中引用类似于指针,但是最终我们使用时是看不到ffdf70的。访问refVal就是访问变量a的地址,编译器屏蔽了底层实现的细节!!!

继续单步调试:

double dval = 3.456;
const int &ri = dval;

上述两句代码的汇编语句是从7d0~7ed

相关汇编的含义是:

movsd 0x128(%rip),%xmm0  从内存中以当前指令指针加上0x128字节的地址开始的位置读取一个双精度浮点数,并将其存放到%xmm0寄存器中。

cvttsd2si %xmm0,%eax 是一条将双精度浮点数(Double-Precision Floating-Point)转换为32位整数的汇编指令,即将3.456转化为3

mov    %eax,-0x24(%rbp) 将3存放在栈空间$rbp-0x24处,这个3是个临时量对象。

lea    -0x24(%rbp),%rax

mov    %rax,-0x10(%rbp) ffdf6c的地址存放到栈空间$rbp-0x10

double dval = 3.456;
const int &ri = dval;

//编译器实际将上述代码做了如下形式处理:
const int temp = dval;
const int &ri = temp;

temp的值是3,地址是ffdf6c ,ri绑定的是temp这个临时量,ri类似指针效果,前文已经叙述。

  • 28
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值