C++

C和C++中引用的底层原理

关于引用是否占用内存,和指针的区别

Posted by bbkgl on September 26, 2019

菜菜菜菜菜。

给点希望行不行。

求包养。

其实我们见到的大部分解释都是这么说的:

  • 引用就是变量的别名
  • 引用不占用空间
  • 引用和指针的区别,blablabla…

引用到底占用空间没,占用的话存的是什么?

首先我们来看看对引用取地址会发生什么?

#include <cstdio>

int main() {
    int a = 10;
    int &b = a;
    printf("%x\n%x\n", &a, &b);
    return 0;
}

// 结果输出如下
e99a7dec
e99a7dec

可以看到,对引用取地址其实就是对被引用对象取地址,所以这样肯定行不通。。

但是,我们可以通过地址偏移来间接实现。

#include <cstdio>

class Test {
public:
    int a = 10;
    int &b = a;
};

int main() {
    Test t, *pt = &t;
    printf("sizeof int is %d.\n", sizeof (int));
    printf("sizeof Test is %d.\nsizeof (int *) is %d.\n", sizeof t, sizeof (int *));
    printf("%x---%d\n", pt, *pt);
    int *ptt = (int *)pt;   // 首先拿到对象的地址,并转成int*类型,便于我们偏移
    printf("%x---%x\n", ptt - 2, *(ptt - 2));  // 利用偏移量就可以拿到引用成员变量的地址和存储的值
    return 0;
}

// 输出
sizeof int is 4.
sizeof Test is 16.
sizeof (int *) is 8.
24cb9ff0---10
24cb9fe8---24cb9ff0

根据输出就可以总结出如下信息:

  • 一个int类型占用空间大小为4字节,int*类型占用空间大小为8(64位)
  • 一个Test对象占用空间大小为16是因为内存对齐,4+8变成了8+8
  • 根据上述两个结论可以得出,引用占用空间,且和指针占用空间一样大
  • 根据最后两个输出可以得出,引用中存放的值就是被引用变量的地址

引用是不是指针?

从底层实现来说,引用就是通过指针实现的,底层就是指针。。。这个的验证可以参考c++中“引用”的底层实现原理详解

但为什么对引用不能像指针一样操作呢?

其实就是像大部分博客和教材中说的那样,引用的出现就是希望开发者们把引用当成变量的别名来使用,具体怎么做到的,我也不知道了。