首页 > 编程语言 >C++ 中的左值引用和右值引用

C++ 中的左值引用和右值引用

时间:2024-09-10 21:18:28浏览次数:1  
标签:const 右值 int 左值 C++ 引用 b1

1、前言概念

左值引用一直有这个概念。C++11中才出现了右值引用的概念。
注意本文只讨论左值引用和右值引用,但需要提前了解一下左值和右值。

    // 以下的a、p、*p、b都是左值
    int a = 3;
    int* p = &a;
    *p;
    const int b = 2;

    double x = 1.3, y = 3.8;
    // 以下几个都是常见的右值
    10;                 // 字面常量
    x + y;             // 表达式返回值
    fmin(x, y);        // 传值返回函数的返回值

简单来说,可以取地址的就是左值,无法取地址的就是右值。或者说在作用域内,内存可以常驻的就是左值,内存无法常驻的就是右值。

2、(非const的)左值引用 【避免对象拷贝】

    T &v = XXX;这个样子的引用叫做左值引用。例如下面代码中,a就是左值引用。顾名思义,左值引用表示引用的内容是一个左值,代码中的a所引用的内容是x,而x是一个左值。

    int x = 3;
    int y = 4;
    int &a = x; //正确
    int &b = 6; //错误
    int &c = x + y;//错误

左值类似于一个别名,主要是为了防止拷贝对象。左值引用只能指向左值(此处的指向二字,可能不太准确,理解意思即可),因为右值的临时分配的没有常驻内存,无法有别名。

3、const左值引用

带了const,就比较特殊了,const左值引用可以指向右值。如:

int x = 4, y = 5;
int &r = x + y; //错误
const int &t = x + y; //OK

所以带了const后的左值引用,所指向的内存就会常驻(不会被自动释放)。但是不能改变其值。

问:为什么const左值引用也可以引用右值?
    答:在 C++11标准产生之前,是没有右值引用这个概念的,当时如果想要一个类型既能接收左值也能接收右值的话,需要用const左值引用,比如标准容器的 push_back 接口:void push_back (const T& val)。
也就是说,如果const左值引用不能引用右值的话,有些接口就不好支持了。
另外,const左值引用,本意上是指向一个不被(该引用本身)它修改的内存区域,本质上这个引用变量本身也就是一个常量,至于这个内存区域对应一个全局变量、局部变量、xvalue,无所谓啊。

如下比较可以看看:

void push_back1(int &val);
void push_back2(const int &val);

int x = 3, y = 5;
push_back1(x+y); //错误
push_back2(x+y); //正确

4、右值引用【延长对象生命周期】

左值引用和const左值引用貌似就够用了,那为啥还需要右值引用呢?
考虑一个场景1需求:为了效率,我不想拷贝构造,但是我又想改变返回值。

int x = 1,y = 2;
int &r = x + y; //无法编译通过,所以无法满足我的场景需求 
const int &r = x + y; //无法改变内容,所以无法满足我的场景1需求 

此时右值引用就应运而生。
右值引用就是对右值的引用,给右值取别名。主要作用是把延长对象的生命周期,一般是延长到作用域的scope之外。

int x = 3,y = 4;
int &&r = x + y; //编译通过
r = 14;//而且可以改变值

//注意,编译的时候需要加上 -std=c++11

右值引用 引用 右值,会使右值被存储到特定的位置。
也就是说,右值引用变量其实是左值,可以对它取地址和赋值。

再看一个场景2需求,如下代码,由于myFun的返回值是一个右值,所以b=myFun()会进入等号操作符。我的需求是需要修改b1的内容,由于参数是const引用所以无法修改b1内容。那如果我将const B &b1的const去掉呢,那么就编译错误了,因为参数b1是一个左值引用无法指向myFun()的返回值(其返回值是个右值)。

class B{
public:
    B& operator=(const B &b1)//const不能去掉,否则编译失败
    //B& operator=(B &b1)//编译失败
    //B& operator=(B &&b1)//皆大欢喜
    {    
    //需要修改b1里的一些内容
        b1.Xxx=  xxx;
        free(b1.xxx);
        return *(this)   
    }
};

B myFun(){
    return B();
}

B b;
b = myFun();

虽然需求有些诡异,但是需要满足的需求只能通过右值引用了。同理使用&&来解决这个问题。只要将const B &b1改为B &&b1就可以了。既可以编译通过,也可以修改其内容。


参考:https://www.cnblogs.com/david-china/p/17080072.html

https://www.bilibili.com/video/BV1ZA41167eL/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=b9fb6f3ca964535da3ae80a5cba37c7a

标签:const,右值,int,左值,C++,引用,b1
From: https://www.cnblogs.com/dongfangchun/p/18407208

相关文章

  • 判断数正负C++
    给定一个整数N,判断其正负。如果N>0,输出positive;如果N=0,输出zero;如果N<0,输出negative。输入输入一个整数N(−109≤N≤109)N(−10​9​​≤N≤10​9​​)输出如果N>0,输出positive;如果N=0,输出zero;如果N<0,输出negative。样例输入1        1样例输......
  • C++:使自定义类支持迭代器
    概述在C++中,链表迭代器是一种用来遍历链表(如std::list)元素的工具。链表是一种数据结构,其中每个元素(节点)包含一个数据值和一个指向下一个节点的指针。链表迭代器允许以类似于数组的方式访问链表中的元素,但不需要直接操作指针。链表迭代器的作用访问元素:链表迭代器使你能够......
  • C++ 多线程详解:从基础到应用
    目录一、什么是多线程?二、C++中的多线程支持三、总结在现代应用中,多线程成为了提升程序性能的重要工具。特别是当我们希望充分利用多核CPU的计算能力时,C++提供了强大的多线程支持,可以并发地执行多个任务。今天,我们将通过易懂的讲解与实际的代码示例,帮助你掌握C+......
  • C++环境搭建(Visual Studio 2022软件安装)
    安装环境:Windows11家庭中文版VisualStudio2022下载地址:        https://pan.baidu.com/s/15U8AEIwThxp-fAZFJqnCgQ    提取码:0000 安装步骤:        1.下载后选择安装包进行解压。    2.以管理员身份运行安装程序。(企业版功能最全,这......
  • C++入门知识
    目录C++是什么C++关键字(c++98)命名空间(namespace)命名空间的定义 命名空间使用声明和定义 C++的输入输出缺省函数缺省函数是什么?全缺省半缺省注意一:半缺省只能从右向左给,并且不能中断 缺省函数不能同时在声明和定义中出现缺省的参数只能是全局的或者常数函数......
  • C++中STL容器的使用
    容器一些基本操作语法vector初始化操作vector<int>a;//声明向量vector<int>a(10);//声明一个初始大小为10的向量vector<int>a(10,1);//初始大小为10,且值都为1的向量vector<int>b(a);//声明并用向量a初始化向量bvector<int>b(a.begin(),a.begin()+3);//将......
  • ubuntu20.04 Qt6引用dcmtk库实现dicom文件读取和字符集转换
    1环境问题安装完Qt6,新建Qt/QtQuickCMake工程编译出现如下错误:Foundpackageconfigurationfile:Qt6Config.cmakebutitsetQt6FOUNDtoFALSEsopackage"Qt6"isconsideredtobeNOTFOUND.原因:这是因为系统中缺少OpenGL库,可以安装libgl1-mesa-dev解决方法:su......
  • 最简单C++线程和互斥锁使用示例
    std::thread是C++11标准库中引入的一个类,用于表示一个独立的执行线程。而std::mutex是C++11中提供的一种互斥锁,用于在多个线程间同步对共享数据的访问,以避免数据竞争和条件竞争。下面将分别介绍std::thread和std::mutex的基本使用,并通过一个示例展示它们的结合使用......
  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【回溯】2024E-字符串
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路代码pythonjavacpp时空复杂度华为OD算法/大厂面......
  • 【C++】priority_queue讲解
    一、priority_queue的本质priority_queue的本质就是堆,添加的元素按照堆的规则存储,默认情况下是大堆。二、priority_queue的参数priority_queue有三个参数。intmain(){priority_queue<int,vector<int>,less<int>>s;//第一个参数为要存放的数据类型//第......