C++中的左值、右值和左值引用、右值引用相关问题

一.什么是左值、右值?

C++( 包括 C) 中所有的表达式和变量要么是左值,要么是右值。通俗的左值的定义就是非临时对象,那些可以在多条语句中使用的对象。所有的变量都满足这个定义,在多条代码中都可以使用,都是左值。右值是指临时的对象,它们只在当前的语句中有效。举几个列子就更好判断了:

int i = 0;

i为左值,0为右值;

((i>0) ? i : j) = 1;

i、j为左值,0、1为右值;
可见左右值并不是以在赋值=号左右边来区分的,主要看是非零时对象还是零时对象。

还有一些特殊的右值出现在这些表达式中:
1.除非return一个局部变量的时候,否则变量名肯定不是右值:
当返回值类型是基本数据类型时也就是一般的函数,return局部变量时会先将局部变量拷贝到一个零时变量中,这个时候返回的其实是右值(零时对象),可以传入到形参为右值引用的函数中,但是返回值类型确不能为右值引用的;

int put()  //虽然queren函数形参为右值引用,但是这边返回值类型为int&&会报错
{
    int temp ;
    temp = 2;
    return temp;
}

int queren(int&& a)
{
    cout << "1";
    return 1;
}


int main()
{
    queren(put());
    return 0;
}

2.当return的是全局变量时,返回的就是左值,这个时候
可以函数的返回值类型可以是 int&,即左值引用类型。

3.表达式的返回值是一个值类型的时候,那么当我们对这个表达式求值的时候,返回值所代表的对象可以被看成一个右值。(原理跟普通函数应该是一样的,但是经过测试,既可以是左值也可以是右值优先为右值)

如下面这段代码:Sum初始化时,两个构造函数都可以调用,当然有右值引用构造函数会优先调用

#include <iostream>
#include <vector>

using namespace std;

vector<int> MakeVector(int start,int stop)
{
    vector<int> numbers;
    for (int i = start; i < stop; i++)
    {
        numbers.push_back(i);
    }
    return numbers;
}
class Sum
{
    private:
        vector<int> numbers;
    public:
        explicit Sum(const vector<int>& theNumbers)
        :numbers{theNumbers}
        {
            cout << "123\n";
        }
        explicit Sum(const vector<int>&& theNumbers)
        :numbers{theNumbers}
        {
            cout << "1234\n";
        }
        int Get()
        {
            int sum = 0;
            for(auto i : numbers)
            {
                sum += i;
            }
            return sum;
        }
};
int main()
{
    Sum sum{MakeVector(1, 10)};
    cout << sum.Get() << endl;
    return 0;
}

4.表达式的返回值是右值引用的时候,那肯定就是右值。

但是如果临时对象通过一个接受右值的函数传递给另一个函数时,就会变成左值,因为这个临时对象在传递过程中,变成了命名对象。

示例程序 :

void process_value(int& i) { 
 std::cout << "LValue processed: " << i << std::endl; 
} 
 
void process_value(int&& i) { 
 std::cout << "RValue processed: " << i << std::endl; 
} 
 
void forward_value(int&& i) { 
 process_value(i); 
} 
 
int main() { 
 int a = 0; 
 process_value(a); 
 process_value(1); 
 forward_value(2); 
}

运行结果 :

LValue processed: 0
RValue processed: 1
LValue processed: 2
虽然 2 这个立即数在函数 forward_value 接收时是右值,但到了 process_value 接收时,变成了左值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值