CD7.C-Dev引用reference-下
目录
CD7.【C++ Dev】引用&(reference) 下
承接 文章
1.练习1
下面代码是否有问题?
int function1()
{
static int x = 0;
return x;
}
int main()
{
int& ret = function1();
return 0;
}
解
有引用,可能出现权限的问题 ,这里权限 放大 了
return x;由于返回类型为int,而返回值由临时变量接收,临时变量具有常属性(只可读),那么使用int&来接收属于权限的放大
(从只可读放大成可读可写),是不被允许的
改法1:权限的平移
int function1()
{
static int x = 0;
return x;
}
int main()
{
const int& ret = function1();
return 0;
}
用const修饰,变成具有常属性,
权限可以平移
改法2:直接复制返回值
不使用引用&,直接复制返回值
int function1()
{
static int x = 0;
return x;
}
int main()
{
int ret = function1();//ret可读可写
return 0;
}
2.练习2
对于如下函数其接收返回值有几种写法?
int& function2()
{
static int x = 0;
return x;
}
写法1:权限的平移
int main()
{
int& ret = function2();
return 0;
}
function2()返回的是x的别名,因此使用int&同级接收(平移权限)
权限不变,即可读可写
写法2:权限的缩小
int main()
{
const int& ret = function2();
return 0;
}
权限从可读可写变成只可读(const修饰)
3.函数返回值(临时变量)分析
对比练习1和练习2函数返回值的接收方式
debug+x64平台下
function1:
直接返回x的值
function2:
返回x的地址(
引用在底层上是指针数学的 )
临时变量的其他场景
例如隐式类型转换:
int main()
{
int i = 1;
double d = 3.14;
if (i > d)
{
return 1;
}
return 0;
}
if在比较i和d时候,发现i和d是不同的类型,只有相同类型才能比较大小,因此int类型的i会被提升为double类型, 提升的结果暂时存储到临时变量(其实是寄存器)中,但i仍然为int类型
debug+x64反汇编代码分析:
解析两个指令:
1.cvtsi2sd 网站的部分描述
简要作用:将双字整型转换为双精度浮点型
则可知
cvtsi2sd xmm0,dword ptr [i] 作用为:将i的值转换为double类型存储到xmm0寄存器中
2.comisd:下图截取了 网站的部分描述
简要作用:
比较双精度浮点型值 并设置EFLAGS标志寄存器
则可知
comisd xmm0,dword ptr [d] 作用为:比较转换成双精度的i和d的值
4.引用实质的两个角度的理解
角度1:语法层面未开空间 角度2:底层开了空间
分析底层开了空间
比较分割线上下两段代码,在底层上是否有区别?
int main()
{
int a = 1;
int& b = a;
//=============
int c = 2;
int* pc = &c;
return 0;
}
解:观察反汇编指令
int a = 1;
mov dword ptr [a],1
int& b = a;
lea rax,[a]
mov qword ptr [b],rax
//=============
int c = 2;
mov dword ptr [c],2
int* pc = &c;
lea rax,[c]
mov qword ptr [pc],rax
上下两段代码的格式完全一样,引用和一级指针的写法没有区别,底层的引用是存储a的地址到b中
5.面试题:分析引用和指针的区别
- 概念上
- 引用定义一个变量的别名,指针存储一个变量地址
- 初始化上
- 引用在定义时必须初始化,指针没有要求
- 引用的特殊性
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
- 是否可为NULL
- 没有NULL引用,但有NULL指针
- sizeof含义
- 引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
- 运算
- 例如引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 是否有多级
- 有多级指针,但是没有多级引用
- 访问实体方式
- 指针需要显式解引用,引用编译器自己处理
- 安全性
- 引用比指针使用起来相对更安全