首页 > 编程语言 >C++填坑系列——左值和右值

C++填坑系列——左值和右值

时间:2024-03-02 12:33:32浏览次数:31  
标签:11 右值 ++ 左值 c++ int 填坑 C++

c++的表达式

首先介绍下c++的表达式是什么?看下cppreference是怎么说的。

An expression is a sequence of operators and their operands, that specifies a computation.

也就是说,在C++中,表达式(Expression)是由操作数(Operands)和运算符(Operators)组成的序列。

左值和右值就是c++中表达式的两种分类。

左值

简单理解,能够取地址的对象是左值,非临时对象的就是左值。

int a = 5;  // a就可以理解成是一个左值,5就可以理解为是一个右值
"hello world";  // 字符串常量值是个左值;字符串常量会申请内存空间,同样的字符串常量使用的是同一块内存;
Object &&obj = std::move();  // 右值引用本身也是个左值,他就是个变量其实,所以也有地址;

右值

c++11之前左值和右值的说法,c++11之后有了细分,又出现了纯右值和将亡值。c++11之前的右值就可以理解为c++11之后的纯右值,这里就直接说纯右值和将亡值了。

纯右值

  1. 纯粹的字面值,如 11false 等;
  2. 求值结果相当于字面值/一个临时对象。
  • 注1:字符串字面值是左值,它是可以进行取地址的操作;
std::cout << &("hello world") << std::endl;

输出的结果是0x100a2df44

  • 注2:++i 是左值,i++是右值

++i 和 i++类似于下面的代码,func1()返回的是一个临时对象;func2()返回的还是 i,用以区分左值还是右值。

// i++
int func1(int &i) {
  int tmp = i;
  i = i + 1;
  return tmp;
}
// ++i
int func2(int &i) {
  i = i + 1;
  return i;
}

将亡值

c++11 之前的右值和 c++11 的纯右值是等价的。

c++11 提出的将亡值是随右值引用引入的,将亡值和右值引用息息相关,将亡值可以按照字面意思来理解,就是快要“死亡”的值。

将亡值表达式:

  1. 返回右值引用的函数调用表达式;例如get_value()返回一个非引用类型的对象;
  2. 转换(cast)为右值引用的转换函数表达式。

何为“将亡”?

c++11 中,

  1. 用左值初始化一个对象/为一个已有对象赋值,会调用拷贝构造函数/拷贝赋值运算符,进行资源拷贝;
  2. 用右值来初始化/赋值时,会调用移动构造函数/移动赋值运算符来移动资源,避免资源拷贝。

当该右值完成初始化/赋值操作后,它的资源已经被移走了,同时该右值会马上被销毁,这就是“将亡”。

std::move()static_cast<X&&>()将左值转为右值,这里就涉及到了将亡值,转换为右值之后原值就被销毁掉了。

标签:11,右值,++,左值,c++,int,填坑,C++
From: https://www.cnblogs.com/pplearn/p/18048484

相关文章

  • C++填坑系列——lambda表达式
    lambda表达式总结:lambda表达式原理:被编译器转换为类+初始化对象的代码;格式:[captureslist](paramslist)specifiersexception->retType{funtionbody}按值捕获和按引用捕获的优缺点以及解决方法;一.lambda原理lambda函数会被编译器转换为类,并定义实现一个operato......
  • C++ 类访问修饰符
    私有(private)成员成员和类的默认访问修饰符是private,如果没有使用任何访问修饰符,类的成员将被假定为私有成员。私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。实际操作中,我们一般会在私有区域定义数据,在公有区域定义相关的函数......
  • C++类开发的第六篇(虚拟继承实现原理和cl命令的使用的bug修复)
    Class_memory接上一篇末尾虚拟继承的简单介绍之后,这篇来详细讲一下这个内存大小是怎么分配的。使用clcl是MicrosoftVisualStudio中的C/C++编译器命令。通过在命令行中键入cl命令,可以调用VisualStudio的编译器进行编译操作。cl命令提供了各种选项和参数,用于指定源......
  • C++ 把引用作为返回值
    通过使用引用来替代指针,会使C++程序更容易阅读和维护。C++函数可以返回一个引用,方式与返回一个指针类似。当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。例如,请看下面这个简单的程序:1#include<iostream>23usingnamesp......
  • C++ 类的内存布局
    基类类内成员的内存分布常见类内成员大致分为:类内变量、类内函数、静态变量、虚函数等,内存分布遵循:所有成员会按照声明的顺序布局类内成员会进行大对齐类内函数不占用类的内存,存储在代码区静态变量不占用类的内存,存储在全局/静态区所有虚函数共用一个虚函数表指针,虚函数表......
  • C++ 把引用作为参数
    1#include<iostream>2usingnamespacestd;34//函数声明5voidswap(int&x,int&y);67intmain()8{9//局部变量声明10inta=100;11intb=200;1213cout<<"交换前,a的值:"<<a<<en......
  • C++ 从函数返回指针
    C++允许从函数返回指针,必须声明一个返回指针的函数:int*myFunction()C++不支持在函数外返回局部变量的地址,除非定义局部变量为static变量。1#include<iostream>2#include<ctime>3#include<cstdlib>4 5usingnamespacestd;6 7//要生成和返回随......
  • C++ 指针 vs 数组
    指针和数组并不是完全互换的1#include<iostream>23usingnamespacestd;4constintMAX=3;56intmain()7{8intvar[MAX]={10,100,200};910for(inti=0;i<MAX;i++)11{12*var=i;//这是正确的语法13......
  • C++类开发第五篇(继承和派生的初体验)
    inheritance在C++中,继承是一种面向对象编程的特性,允许一个类(称为子类或派生类)从另一个类(称为基类或父类)那里继承属性和行为。通过继承,子类可以获得父类的数据成员和成员函数,从而可以重用父类的代码并扩展其功能。这样可以提高代码的复用性和可维护性,同时也符合面向对象编程的封......
  • C++static 存储类
    1#include<iostream>23//函数声明4voidfunc(void);56intmain()7{8intcount=10;9while(count--)10{11func();12std::cout<<",变量count为"<<count<<std::endl;13......