C++中的左值、右值、左值引用、右值引用的对比区分


前言

本文对C++中的左值、右值、左值引用、右值引用进行对比区分


一、左/右值是什么?

左值:一般出现在赋值运算符左侧的,具名且可以取地址的变量;
右值:只能出现在赋值运算符右侧的表达式或函数返回值,常量,无名且不能取地址;

int a = 1;//a为左值,1为右值
int b = a+2;//b为左值,(a+2)是一个表达式,为右值

二、左/右值引用

1.左值引用

一般C++中的引用就是指的左值引用,它必须使用左值初始化(const左值引用除外)
如下:

int a = 1;
int &r_a1 = a;
int &r_a2 = 1;//error
const int &r_a3 = 1;//right

2.右值引用

右值引用是对临时变量,将要消亡的值的引用,也需要定义时初始化,是C++中引入的支持移动语义的新的特性。
移动语义:在资源转移时避免不必要的拷贝,从而提高内存使用性能;例如原先拷贝初始化时,需要给目标对象创建新的内存,并将原对象的值进行拷贝,再释放原对象的内存。移动构造函数或移动赋值运算符则可以在原对象的基础上直接构造新的对象而避免了内存申请的开销。
如下是一个使用右值引用的实例:

#include <iostream>

class MyClass {
private:
    int* data;

public:
    MyClass() {
        data = new int[10];
        std::cout << "Default constructor called" << std::endl;
    }

    MyClass(const MyClass& other) {  // 拷贝构造函数
        data = new int[10];
        std::copy(other.data, other.data + 10, data);
        std::cout << "Copy constructor called" << std::endl;
    }

    MyClass(MyClass&& other) {  // 移动构造函数,使用右值引用
        data = other.data;
        other.data = nullptr;
        std::cout << "Move constructor called" << std::endl;
    }

    ~MyClass() {
        delete[] data;
    }

    void printData() {
        for (int i = 0; i < 10; ++i) {
            std::cout << data[i] << " ";
        }
        std::cout << std::endl;
    }
};

MyClass createObject() {
    MyClass obj;
    return obj;
}

int main() {
    MyClass obj1;
    obj1.printData();

    MyClass obj2 = createObject();  // 这里会调用移动构造函数
    obj2.printData();

    return 0;
}

总结

这里对文章进行对比总结:

特性/概念左值 (lvalue)右值 (rvalue)
定义能够被取地址,代表一个对象的身份不能被取地址,代表一个对象的值
用途可以出现在赋值表达式的左侧,可以被多次访问通常出现在赋值表达式的右侧,用于传递值
类型变量、数组、对象成员等临时对象、字面量、返回值等
返回类型可以返回左值引用可以返回右值引用或左值引用
修饰符通常不需要 const可以被 const 修饰,形成 const rvalue reference
常用场景函数参数,需要修改对象时移动语义,函数参数,需要获取对象所有权时
与引用的关系左值引用可以绑定到左值右值引用可以绑定到左值或右值
特性/概念左值引用 (&)右值引用 (&&)
定义引用一个对象,必须绑定到对象上引用一个对象,但可以绑定到对象或对象的临时状态
用途用于获取对象的别名用于接受对象的所有权,或者引用临时对象
与对象的关系必须引用一个已存在的对象可以引用一个临时对象或已存在的对象
返回类型返回左值引用返回右值引用
修饰符const 修饰的左值引用为 const T&const 修饰的右值引用为 const T&&
常用场景函数参数,需要修改对象时移动语义,函数参数,需要获取对象所有权时
std::move无直接关系使用 std::move 可以将左值转换为右值引用
  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小凡下方了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值