首页 > 编程语言 >C++ 引用底层解析

C++ 引用底层解析

时间:2024-03-20 20:46:57浏览次数:30  
标签:变量 int C++ eax 引用 dword 解析 ri 底层

1. 引用的底层原理解析

引用被称为变量的别名,它不能脱离被引用对象独立存在,这是在高级语言层面的概念和理解,并未揭示引用的实现方式。常见错误说法是“引用“自身不是一个变量,甚至编译器可以不为引用分配空间。

引用地址空间存放的是被引用对象的地址。

实际上,引用本身是一个变量,只不过这个变量的定义和使用与普通变量有显著的不同。为了解引用变量底层实现机制,考查如下代码:

int i = 5;
int &ri = i;
ri = 8;

在Visual Studio 2017环境的debug模式调试代码,反汇编查看源码对应的汇编代码的步骤是:调试->窗口->反汇编,即可得到如下原码对应的汇编代码:

int i = 5;
00A013DE  mov        dword ptr [i],5      # 将文字常量5送入变量i

int &ri = i;
00A013E5  lea        eax,[i]              # 将变量i的地址送入寄存器eax
00A013E8  mov        dword ptr [ri],eax   # 将寄存器的内容(也就是变量i的地址)送入变量ri

ri = 8;
00A013EB  mov        eax,dword ptr [ri]   # 将变量ri的值送入寄存器eax
00A013EE  mov        dword ptr [eax],8    # 将数值8送入以eax的内容为地址的单元中

return 0;
00A013F4  xor        eax,eax

考查以上代码,在汇编代码中,ri的数据类型为dword,也就是说,ri要在内存中占据4个字节的位置。所以,ri的确是一个变量,它存放的是被引用对象的地址。由于通常情况下,地址是由指针变量存放的,那么,指针变量和引用变量有什么区别呢?使用指针常量实现上面的代码功能。考查如下代码:

int i = 5;
int* const pi = &i;
*pi = 8;

 按照相同的方式,在VS2017中得到如下汇编代码:

int i=5;
011F13DE  mov         dword ptr [i],5  

int * const pi = &i;
011F13E5  lea         eax,[i]  
011F13E8  mov         dword ptr [pi],eax 

*pi = 8;
011F13EB  mov         eax,dword ptr [pi]  
011F13EE  mov         dword ptr [eax],8  

观察以上代码可以看出:

  • 只要将pi换成ri,所得汇编代码与第一段所对应的汇编代码完全一样。所以,引用变量在功能上等于一个指针常量,即一旦指向某一个单元就不能在指向别处。
  • 在底层,引用变量由指针按照指针常量的方式实现。
  • 引用是一种更安全的指针,因为引用必须初始化,不会出现空指针或野指针。
  • 存在多级指针,但不存在多级引用。

2. 引用与数组间的关系

引用可以作为数组元素的别名:

int a[3] = { 1, 2, 3 };
int& b = a[0];
b = 4;
cout << a[0] << endl;

引用只有在分配内存的时候才必须初始化:

struct Test {
	int& a;
}
cout << sizeof(Test) << endl; // 8
Test test;
cout << sizeof(test) << endl; // 报错

不能建立引用数组:

int a[3] = {1, 2, 3};
int &b = a;

 

标签:变量,int,C++,eax,引用,dword,解析,ri,底层
From: https://www.cnblogs.com/love-9/p/18086025

相关文章

  • C++ extern
    extern有两个作用:当它与”C”一起连用时,如:extern“C”voidfun(inta,intb);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的。C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因......
  • socket 技术是干什么的?底层原理是什么?
    Socket技术是一种通信机制,用于实现不同计算机之间的网络通信和同一计算机内不同进程之间的进程间通信。它是一种抽象层,使得不同操作系统和编程语言的程序能够在网络上相互通信。底层原理方面,Socket技术基于网络协议栈和操作系统提供的网络编程接口。当程序使用Socket技术......
  • C++初阶:初识模板
        在之前的C与C++编程中,针对实现同样类型功能的函数我们学会使用了函数重载,终于可以不用记忆多个功能相同但是函数名不同的函数了喵。但是在实现的时候仍然显得有点不太方便,有些冗余。世界是懒人的世界,为了方便懒人的使用,模板应运而生~目录一、引子二、函数模......
  • 复试C++14真题 看程序写结果5 虚函数、继承 易错?
    复试C++14真题 看程序写结果5  虚函数、继承#include<iostream>usingnamespacestd;classA{public:virtualvoidprint(){cout<<"A::print"<<endl;}//voidprint(){cout<<"A::print"<<endl;}};classB:public......
  • (C++20) jthread中stop_token的基础使用
    (C++20)jthread中stop_token的基础使用文章目录(C++20)jthread中stop_token的基础使用C++20jthread使用方式循环判断条件变量condition_variable_anystop回调std::stop_callbackENDC++20jthreadstd::jthread-cppreference.comstd::stop_token-cpprefere......
  • 深入了解鸿鹄工程项目管理系统源码:功能清单与项目模块的深度解析
     工程项目管理软件是现代项目管理中不可或缺的工具,它能够帮助项目团队更高效地组织和协调工作。本文将介绍一款功能强大的工程项目管理软件,该软件采用先进的Vue、Uniapp、Layui等技术框架,涵盖了项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营等全过程。通过......
  • c++简介
    C++(cplusplus)是一种计算机高级程序设计语言,由C语言扩展升级而产生[17],最早于1979年由本贾尼·斯特劳斯特卢普在AT&T贝尔工作室研发。C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的......
  • C++面向对象整理(1)之初识类和对象
    C++面向对象整理(1)之初识类和对象注:整理一些突然学到的C++知识,随时mark一下例如:忘记的关键字用法,新关键字,新数据结构C++的类和对象C++面向对象整理(1)之初识类和对象一、类的定义1、类成员的访问权限2、类定义示例(1)类内定义(2)类外定义成员函数3、类对象(实例)的定义及......
  • javascript:void(0);用法及常见问题解析
    javascript:void(0);是一个常见的JavaScript代码片段,通常用于在HTML中作为超链接的href属性值或者事件处理函数的返回值。下面是关于它的用法和常见问题的解析:用法:作为超链接的href属性值:<ahref="javascript:void(0);">点击这里</a>这样做的作用是让点击链......
  • C++ static函数调用问题
    静态成员变量虽然在类中,但它并不是随对象的建立而分配空间的,也不是随对象的撤销而释放(一般的成员在对象建立时会分配空间,在对象撤销时会释放)。静态成员变量是在程序编译时分配空间,而在程序结束时释放空间。静态成员的定义和声明要加个关键static。静态成员可以通过双冒号来使用......