C++ 左值和右值

2022/7/9 14:22:11

本文主要是介绍C++ 左值和右值,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

本文转自:https://www.cnblogs.com/relaxease/p/16027916.html

C++的左值和右值

摘要

C++语言中的左值和右值是困扰我的知识点,今天将学习到的知识点整理一下,以理清概念。本文首先介绍了左值、右值的一般分类和概念,包括广义左值,将亡值和纯右值,然后介绍了我对左值和右值的理解:将左值理解成水桶,将右值理解成水,最后介绍了左值引用和对常量的左值引用。

表达式值的分类

本文说的左值(lvalue)和右值(rvalue),其中的“值”就是表达式(expression)的值。C++17标准定义了表达式值的分类,其主要分为3类:

  • 广义左值(glvalue):在程序员编程时,程序员可以取地址的东西(对象、函数)。举例:变量、函数等。
  • 纯右值(prvalue):在程序员编程时,程序员不可以取地址的东西。举例:字面值常量。
  • 将亡值(xvalue):本身可以被程序员取地址,但是马上就不能被取地址了的东西。

这三种类别和左右值的关系图:


三种类别和左右值的关系图
可以看出,右值包含了纯右值和将亡值。

总结一下,可以这么理解左值和右值:左值,就是可以取地址的东西;右值就是不可以取地址的东西。

左右值的理解

我把左值理解成水桶,右值理解成水。这样我感觉比较好记忆和理解。比如:

int x; //x左值,理解成一个水桶
x = 10; // 10是右值,理解成水
int *p = &x; // 可以对水桶取地址,找到放水桶的地址
&10; // 编译错误,水没有位置,不能取地址
int y = x; // 把x水桶里的水复制一份到y水桶。

又如:

int f() { 
    int x = 10; // x是一个水桶
    return x; //但是要被返回了,也就是这个水桶要被“销毁”。
} 

int main() {
    f() = 10; //编译错误,水桶已被销毁,不能盛水了
    return 0;
}

左值引用

左值引用,就是在水桶上贴上了一个标签,这个标签代表了水桶(其实变量名字也可以理解成水桶上的标签)。
比如:

int a = 10;
int &b = a; //贴上标签

注意到常量的左值引用可以绑定到字面值常量上,也就是说以下代码是正确的:

const int & c = 10; //编译正确,但是“10”是右值,理解成水,c是左值引用,理解成标签。

但是如果把左值引用理解成在水桶上贴标签的话,以上代码就与这个理解产生冲突了。毕竟“标签”不能贴到“水”上。
其实,编译器会创建一个隐藏的变量来让引用c绑定到10上。比如:

const int & c = 10; 
//会被翻译成这样:
int __internal_unique_name = 10;
const int& c = __internal_unique_name;

也就是说,编译器会创建一个左值(理解成“水桶”)来存储10(理解成“水”),然后再让引用绑定到该左值上(理解成在水桶上贴标签)。

总结

本文介绍了对左值和右值的理解。如果有什么错误,希望读者可以批评指正!

参考

  • [1]微软C++文档
  • [2]Internal Pointers的博客


这篇关于C++ 左值和右值的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程