作为最重要的一项语言特性,右值引用(rvalue references)被引入到 C++0x中。我们可以通过操作符“&&”来声明一个右值引用,原先在C++中使用“&”操作符声明的引用现在被称为左值引用。

int a;
int& a_lvref = a;  // 左值引用

int b;
int&& b_rvref = b;  // 右值应用

左值引用和右值引用的表现行为基本一致,它们唯一的差别就是右值引用可以绑定到一个临时对象(右值)上,而左值引用不可以。例如:

int& a_lvref = int();      // error C2440: 'initializing' : cannot convert from 'int' to 'int &'    
int&& b_rvref = int();  // OK!

在第一行代码中,我们将一个临时对象int()绑定到一个左值引用,将产生一个编译错误。而在第二行中,我们将临时对象绑定到右值引用,就可以顺利通过编译。

右值是无名的数据,例如函数的返回值一般说来就是右值。当对右值进行操作的时候,右值本身往往没有必要保留,因此在某些情况下可以直接“移动”之。通过右值引用,程序可以明确的区分出传入的参数是否为右值,从而避免了不必要的拷贝,程序的效率也就得到了提高。我们考虑一个简单的数据交换的小程序,从中来体会右值引用所带来的效率提升。我们可以写一个函数swap来实现两个变量值的交换:

template <class T> swap(T& a, T& b)
{
    T tmp(a);   // tmp对象创建后,我们就拥有了a的两份拷贝
    a = b;      // 现在我们拥有b的两份拷贝
    b = tmp;    // 现在我们拥有a的两份拷贝
}

在这段代码中,虽然我们只是为了进行简单的数据交换,但是却执行了多次对象拷贝。这些对象的拷贝操作,特别是当这些对象比较大的时候,无疑会影响程序的效率。

那么,如果使用右值引用如何实现呢?

// RValueRef.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

template <class T> 
T&& move(T&& a)
{
    return a;
}

template <class T> void swap(T& a, T& b)
{
    T tmp(move(a)); // 对象a被移动到对象tmp,a被清空
    a = move(b);    // 对象b被移动到对象a,b被清空
    b = move(tmp);  // 对象tmp被移动到对象b
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 1;
    int b = 2;
    swap(a, b);

return 0;
}

在这段重新实现的代码中,我们使用了一个move()函数来代替对象的赋值操作符“=”,move()只是简单地接受一个右值引用或者左值引用作为参数,然后直接返回相应对象的右值引用。这一过程不会产生拷贝(Copy)操作,而只会将源对象移动(Move)到目标对象。

正是拷贝(Copy)和移动(Move)的差别,使得右值引用成为C++0x中最激动人心的新特性之一。从实践角度讲,它能够完美是解决C++中长久以来为人所诟病的临时对象的效率问题。从语言本身讲,它健全了C++中的引用类型在左值右值方面的缺陷。从库设计者的角度讲,它给库设计者又带来了一把利器。而对于广大的库使用者而言,不动一兵一卒便能够获得“免费的”效率提升。

摘自:http://blog.csdn.net/shellching/archive/2010/04/20/5506019.aspxC++ 新特性-右值引用

最新文章

  1. 我的第一个python程序--给2.x的print代码加上括号
  2. vs2008注册组件
  3. wk_01
  4. 简单实现div遮罩
  5. !!!jQuery中事件绑定 推荐使用.delegate()或者live()
  6. sdk和ndk
  7. 在Myeclipse中移除项目对Hibernate的支持
  8. ZOJ 2015 10月份 月赛 3911 Prime Query
  9. Gradle version 2.10 is required. Current version is 2.8.
  10. 局域网内IP冲突怎么办
  11. hdu2222Keywords Search
  12. PHP - 防止 XSS(跨站脚本攻击)
  13. R学习笔记:了解R的使用
  14. IntelliJ IDEA重启Tomcat
  15. 多线程——newCachedThreadPool线程池
  16. Keystone中间件WSGI环境变量总结
  17. 大数据:Spark Core(二)Driver上的Task的生成、分配、调度
  18. POJ-1456 Supermarket(贪心,并查集优化)
  19. js中准确判断数据类型的方法
  20. apache配置修改

热门文章

  1. HM编码器代码阅读(1)——介绍以及相关知识
  2. MATROSKA 文件格式
  3. 《利用Python进行数据分析》笔记---第2章--1880-2010年间全美婴儿姓名
  4. 从JDK源码角度看Boolean
  5. 用vue实现百度搜索功能
  6. Map集合学习
  7. BZOJ3144 Hnoi2013 切糕 【网络流】*
  8. CDQ分治--用时间降维的美丽算法
  9. 20179223《Linux内核原理与分析》第十一周学习笔记
  10. LintCode题解