在C++中,左值(lvalue)是能够获取其地址的一个量。因为常常出如今赋值语句的左边。因此称之为左值。比如一个有名称的变量。

比如:

int a=10;
//a就是一个左值。

传统的C++引用,都是左值引用。比如:int &ra=a;将ra关联到a。这就是左值引用。

C++11,新增了右值引用的概念。

用&&代表右值引用。

首先我们来看一下什么叫做右值。

能够说全部不是左值的量都是右值。比如文本,暂时对象或者暂时值(都是不能获取地址的量)。

右值引用。就是一个对右值的引用。特别地,这是一个当右值是一个暂时对象时使用的概念。

比如。

int  &&ra=10;

     10就是一个右值。ra将是10这个右值的引用。看样例:

#include <iostream>
using namespace std;
int main()
{
int &&ra=9;
cout<<&ra<<endl<<ra<<endl;
ra=5;
cout<<&ra<<endl<<ra<<endl; cin.get();
}

输出结果:

有趣的是,将右值关联到右值引用将导致该右值被存储到特定的位置,且能够获取该位置的地址。

比如。你不能对右值9或者5进行&运算。可是能够对ra进行&运算。

右值引用的目的是提供一些涉及暂时对象时能够选用特定的方法(主要是复制构造函数以及operator=,但并不限于此)。因为知道暂时对象会被销毁。通过右值引用,某些涉及复制大量数据的操作能够通过简单地复制指向这些值的指针来实现。

方法能够将&&作为參数说明的一部分,从而指定右值引用參数。看样例:

#include <iostream>
using namespace std;
void showMax(int &a,int &b){
if(a>b)
cout<<a<<endl;
else
cout<<b<<endl;
}
int main()
{
int a=10;
int b=5;
showMax(a,b);
//showMax(20,15); // invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'|
cin.get();
return 0;
}

发现showMax(20,15)的时候无法正常编译。

这是由于20,15是一个右值。以下我们定义一个右值引用版本号的showMax();

#include <iostream>
using namespace std;
void showMax(int &a,int &b){
if(a>b)
cout<<a<<endl;
else
cout<<b<<endl;
};
void showMax(int &&a,int &&b){
cout<<"这是一个右值引用比較"<<endl;
if(a>b)
cout<<a<<endl;
else
cout<<b<<endl;
}
int main()
{
int a=10;
int b=5;
showMax(a,b);
showMax(20,15);
return 0;
}

执行结果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXE4NDQzNTIxNTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

当调用showMax(20,15)的时候,编译器将自己主动调用相相应的右值引用的版本号。

作为方法的參数的时候右值引用很实用。又比如:

#include <iostream>
using namespace std;
void show(int &a){
cout<<"左值引用:"<<a<<endl;
};
void show(int &&a){
cout<<"这是一个右值引用:"<<a<<endl;
}
int main()
{
int a=10;
int b=5;
show(a);
show(a+b);
show(a++); //右值引用
show(++a); //左值引用
show(b+100);
show(100+200);
}

结果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXE4NDQzNTIxNTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

须要注意的是:

show(a++);  //右值引用

    show(++a);  //左值引用

a++是先取出持久对象a的一份拷贝,再使持久对象a的值加1,最后返回那份拷贝,而那份拷贝是暂时对象(不能够对其取地址),故其是右值;

++a则是使持久对象a的值加1,并返回那个持久对象a本身(能够对其取地址),故其是左值。

右值引用单独使用的情况非常少。一般都是用于作为方法的參数或者函数的參数。使用的最多的情况则是用在移动语义之上。

C++11新特性(1) 右值引用的更多相关文章

  1. C++11新特性之右值引用(&&)、移动语义(move)、完美转换(forward)

    1. 右值引用 个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能. 比如下面的代码: String Fun() { String str = "hello world"; ...

  2. C++11新特性:右值引用和转移构造函数

    问题背景 #include <iostream> using namespace std; vector<int> doubleValues (const vector< ...

  3. 透彻理解C++11新特性:右值引用、std::move、std::forward

    目录 浅拷贝.深拷贝 左值.右值 右值引用类型 强转右值 std::move 重新审视右值引用 右值引用类型和右值的关系 函数参数传递 函数返还值传递 万能引用 引用折叠 完美转发 std::forw ...

  4. C++11的新特性:右值引用

    先看代码 #include "pch.h" #include <iostream> #include <string> using namespace st ...

  5. [转][c++11]我理解的右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  6. C++11常用特性介绍——左值引用、右值引用

    一.左值.右值 1)左值:可以放在赋值号左侧.可以被赋值的值:左值必须要在内存中有实体. 2)右值:必须放在赋值号右侧.取出值赋值给其它变量:右值可以在内存中也可以在CPU寄存器中. 二.引用 引用是 ...

  7. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  8. C++11新特性之0——移动语义、移动构造函数和右值引用

    C++引用现在分为左值引用(能取得其地址)和 右值引用(不能取得其地址).其实很好理解,左值引用中的左值一般指的是出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引 ...

  9. [转载]如何在C++03中模拟C++11的右值引用std::move特性

    本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...

随机推荐

  1. ButterKnife 注解 bindview

    简介 官网:http://jakewharton.github.io/butterknife/ github:https://github.com/JakeWharton/butterknife 注意 ...

  2. 【Multiple backgrounds】用CSS3实现网页多重背景

    对于背景属性background-image大家应该已经很熟悉了,在CSS2中与它相关的属性还有background-repeat(设置背景是否重复及重复的方式).background-positio ...

  3. Android -- 图片异步上传到PHP服务器

    背景                                                                                           网上很多上传到 ...

  4. Cognos事件工作室Event Studio开发步骤

    Cognos本身是很强大的,只是很多人的思维只是局限在数据-模型-展示的层面上,下面我们就来介绍一下Cognos中稍微有些冷门的一个组件事件工作室(IBM Cognos Event Studio),概 ...

  5. python时间格式化及前推

    import datetime >>> (datetime.datetime.now() - datetime.timedelta(seconds = 300)).strftime( ...

  6. 微信小程序中用户唯一ID的获取

    折腾到半夜,搞得挺兴奋,总结一下,免得忘了: 1.微信小程序直接获得的是一些简单信息,基本无用 2.用户唯一标识是openid,还有一个unionid是关联多个公众号之类情况下用,我不大关心 3.在g ...

  7. WIN32 SDK对COM的支持

     

  8. IO介绍

    IO在计算机中指Input/Output,也就是输入和输出.由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘.网络等,就需要IO接口. 比如你打开 ...

  9. jasperreport 通过javabean datasoource实现chart的报表

    继上次report的demo后,还在继续做着report方面的research,今天主要是实现了通过javabean datasource填充chart图表,通过webservice下载pdf格式的报 ...

  10. uni-app 为何package.json配置以后不会生成文件?

    和微信小程序不同的是uni-app 配置步骤如下 小程序是新建json生成文件夹\文件 uni-app是新建文件生成json