在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. 输错密码?这个 sudo 会“嘲讽”你

    导读 你在 Linux 终端中会有很多的乐趣.我今天要讲的不是在终端中跑火车.我今天要讲的技巧可以放松你的心情.你学习过如何在命令行中增加 sudo 命令的超时,今天的文章中,我会向你展示如何让 su ...

  2. Ionic 4 and the Lifecycle Hooks

    原文: https://medium.com/@paulstelzer/ionic-4-and-the-lifecycle-hooks-4fe9eabb2864 ------------------- ...

  3. (转)UnityVS(Visual Studio Tools For Unity)的安装与使用

    UnityVS(Visual Studio Tools For Unity)的安装与使用   一些废话 Unity 的开发者们,尤其是微软系的Unity开发者们,用Mono是不是烦死了?你是不是跟我一 ...

  4. 6. Activity life cycle

    An activity can exist in essentially three states: Resumed The activity is in the foreground of the ...

  5. Android MVP 构架封装

    上一篇我们简单实现了一个MVP的构架,下面我们来做一个简单的封装使其使用更简单方便 源码地址RxMVP分支Tag03 最终实现目录结构如下 BasePresenter 如果每一个Activity都需要 ...

  6. Linux动态库(.so)搜索路径

    主要内容: 1.Linux动态库.so搜索路径 编译目标代码时指定的动态库搜索路径: 环境变量LD_LIBRARY_PATH指定的动态库搜索路径: 配置文件/etc/ld.so.conf中指定的动态库 ...

  7. 亲自己主动手从源代码 构建 Groovy 2.3.8 公布包

    今天为了学习 怎样使用 Groovy 写 Groovy 的測试代码, 所以到 http://groovy.codehaus.org/Download 下载了 Groovy 2.3.8 的源码包. Gr ...

  8. VB调用VC dll的返回方式

    第一种类型:数值传递 注意:在VB中,默认变量传递方式为ByRef为地址,而传递值就是用ByVal,还要注意在C++中,int类型的变量是32位的,在VB中要用long型变量来配合.VC++部分: e ...

  9. No value for key [org.hibernate.impl.SessionFactoryImpl 异常解决

    使用Hibernate+Spring进行CRUD操作时.出现例如以下类似异常信息: java.lang.IllegalStateException: No value for key [org.hib ...

  10. SettingsSVNPlugin

      迁移时间:2017年5月20日11:24:50CreateTime--2016年9月18日17:53:20Author:Marydonmyeclipse/eclipse中配置svn插件参考链接:h ...