C++语法系列——引用的左值/右值之分

目录

 

(1)为何要区分?

(2)那什么是左值/右值引用?

(3)左值?右值?

(4)左值/右值,与左值/右值引用有什么区别?


(1)为何要区分?

    引用的类型是左值/右值,指明了其绑定的对象的状态是仍有可能被使用,or不再被修改、使用甚至被销毁。而对象的状态(左值/右值)又可决定,如何“拷贝”对象所拥有的动态资源——拷贝or接管。这一操作依赖类内的拷贝/移动构造函数以及拷贝/移动赋值运算符。

下面以vector<int>举例,窥探对象的状态(左值/右值)对“拷贝”对象这一操作的影响:

#define HUGENUM 1000000000 //10亿
int main()
{
    vector<int> A(HUGENUM, 50), B, C; //vector类的对象内拥有动态资源
    clock_t start, end;
    start = clock();
    B = A; // 拷贝资源
    end = clock();
    cout << "time consumed on copy is " << (end - start) / CLK_TCK << endl;
    start = clock();
    C = std::move(A); // 移动(接管)资源
    end = clock();
    cout << "time consumed on move is " << (end - start) / CLK_TCK << endl;
}

运行结果如下:

可见,对于拥有动态资源的对象,其状态(左值/右值)决定了其被“拷贝”时的具体实现,而当对象拥有大量的动态资源时,这一实现会影响到运行效率。

(2)那什么是左值/右值引用?

形式上,定义引用时有一个&修饰符的则为左值引用,有两个&修饰符的则为右值引用。左值/右值引用必须绑定对应状态的对象,如下:

---- 右值引用只能绑定到右值对象上;

---- 非const左值引用只能绑定到左值对象上,而const左值引用对于左值/右值对象均能绑定。(const左值引用无法修改其绑定的对象,这符合右值的设计理念)

(3)左值?右值?

左值可位于赋值号的左侧和右侧,可寻址,其值既能被使用也能被修改。而右值只能位于赋值号右侧,不可寻址,可使用而不可修改其值。

常见左值包括:定义的对象、引用(不论左值/右值)、赋值/下标/解引用/前置自增自减等运算符返回的值,以及返回类型为引用类型的函数所返回的值;

常见右值包括:字面值常量、算数/关系/逻辑/位等运算返回的值、后置自增自减运算符返回的值,以及返回类型为非引用类型的函数所返回的值。

(4)左值/右值,与左值/右值引用有什么区别?

---- 左值/右值引用本身属于左值,既能使用也能修改其绑定的对象的值。但我们在使用右值引用时,还是应该遵循右值的设计理念,即假设右值引用绑定的对象不会再被修改、使用,甚至可能立刻被销毁;

---- 右值引用绑定的既可能是真实的右值如(3)所述,也可能是我们希望是右值但实际并不是的普通对象(利用std::move()转换)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值