网站建设与开发是什么岗位,长沙本土网站建设公司,做非法网站怎么规避,信誉好的购物网站建设目录前言C左值和右值二、右值引用二、右值引用前言
对于C的左值和右值相信很多人都没有一个很透彻的了解,之前我也是不懂的时候查阅了好多文章,但是讲完我还是一头雾水,直到我遇到一篇宝藏文章,讲的左值右值的关系以及Move函数的用法是相当的清楚,文章链接在这,话不多说讲解一…
目录前言C左值和右值二、右值引用二、右值引用前言
对于C的左值和右值相信很多人都没有一个很透彻的了解,之前我也是不懂的时候查阅了好多文章,但是讲完我还是一头雾水,直到我遇到一篇宝藏文章,讲的左值右值的关系以及Move函数的用法是相当的清楚,文章链接在这,话不多说讲解一下 文章链接 C左值和右值
在 C 或者 C 语言中一个表达式可以是字面量、变量、对象、函数的返回值等根据其使用场景不同分为左值表达式和右值表达式。确切的说 C 中左值和右值的概念是从 C 语言继承过来的。 左值的英文简写为“lvalue”右值的英文简写为“rvalue”。很多人认为它们分别是left value、“right value” 的缩写其实不然。lvalue 是“loactor value”的缩写可意为存储在内存中、有明确存储地址可寻址的数据而 rvalue 译为 “read value”指的是那些可以提供数据值的数据不一定可以寻址例如存储于寄存器中的数据。 判断某个表达式是左值还是右值的方法
① 可位于赋值号左侧的表达式就是左值反之只能位于赋值号右侧的表达式就是右值。
int a 5;
5 a; //错误5 不能为左值/*
其中a是一个左值字面值5是一个右值
*/【注意】 C中的左值也可以当作右值使用。
int b 10; // b 是一个左值
a b; // a、b 都是左值只不过将 b 可以当做右值使用② 有名称的、可以获取到存储地址的表达式即为左值反之则是右值。
上述示例中变量 a、b 是变量名且通过 a 和 b 可以获得他们的存储地址因此 a 和 b 都是左值反之字面量 5、10它们既没有名称也无法获取其存储地址字面量通常存储在寄存器中或者和代码存储在一起因此 5、10 都是右值。 二、右值引用
1.右值引用的引入
在C11之前就有引用“”但是此种引用有一个缺陷即正常情况下只能操作 C 中的左值无法对右值添加引用。
int num 10;
int b num; //正确
int c 10; //错误编译器允许我们为 num 左值建立一个引用但不可以为 10 这个右值建立引用。
“”表示的引用又称为左值引用。
【注意】虽然 C98/03 标准不支持为右值建立非常量左值引用但允许使用常量左值引用操作右值。也就是说常量左值引用既可以操作左值也可以操作右值。
int num 10;
const int b num;
const int c 10;右值往往是没有名称的因此要使用它只能借助引用的方式。这就产生一个问题实际开发中我们可能需要对右值进行修改实现移动语义时就需要显然左值引用的方式是行不通的。
为此C11 标准新引入了另一种引用方式称为右值引用用 “” 表示。
2.右值引用的使用 ① 和声明左值引用一样右值引用也必须立即进行初始化操作且只能使用右值进行初始化。
int num 10;
//int a num; //右值引用不能初始化为左值
int a 10;② 右值引用可以修改右值
int a 10;
a 11;
cout a endl; //输出结果为11③C语法之词定义常量右值引用
const int a 10;//编译器不会报错但这种形式的右值引用并没有实际用处。一方面右值引用主要用于移动语义和完美转发其中前者需要有修改右值的权限其次常量右值引用的作用就是引用一个不可修改的右值这项工作完全可以交给常量左值引用完成。
【总结】
①非常量左值引用可以引用的值的类型只有非常量左值常量左值引用非常量左值、常量左值及右值 int num 10;int a num; //编译成功非常量左值引用支持引用非常量左值const int num2 100;int b num2; //编译失败非常量左值引用不支持引用常量左值int c 10; //编译失败非常量左值引用不支持引用右值const int d num; //编译成功常量左值引用支持引用非常量左值const int e num2; //编译成功常量左值引用支持引用常量左值const int f 100; //编译成功常量左值引用支持引用右值②右值引用不支持引用左值非常量右值引用可以引用的值的类型只有非常量右值常量右值引用非常量右值、常量右值 int num 10;const int num2 100;int a num; //编译失败非常量右值引用不支持引用非常量左值int b num2; //编译失败非常量右值引用不支持引用常量左值int c 10; //编译成功非常量右值引用支持引用非常量右值const int d num; //编译失败常量右值引用不支持引用非常量左值const int e num2; //编译失败常量右值引用不支持引用常量左值const int f 100; //编译成功常量右值引用支持引用右值二、右值引用
move()函数的语法格式
move(arg)
//agr:左值对象该函数返回arg对象的右值形式int num 10;int a std::move(num); //编译成功cout a endl; //输出结果为10