做爲最重要的一項語言特性,右值引用(rvalue references)被引入到 C++0x中。咱們能夠經過操做符「&&」來聲明一個右值引用,原先在C++中使用「&」操做符聲明的引用如今被稱爲左值引用。 html
int a;
int& a_lvref = a; // 左值引用
int b;
int&& b_rvref = b; // 右值應用shell
左值引用和右值引用的表現行爲基本一致,它們惟一的差異就是右值引用能夠綁定到一個臨時對象(右值)上,而左值引用不能夠。例如: 小程序
int& a_lvref = int(); // error C2440: 'initializing' : cannot convert from 'int' to 'int &'
int&& b_rvref = int(); // OK!app
在第一行代碼中,咱們將一個臨時對象int()綁定到一個左值引用,將產生一個編譯錯誤。而在第二行中,咱們將臨時對象綁定到右值引用,就能夠順利經過編譯。
右值是無名的數據,例如函數的返回值通常說來就是右值。當對右值進行操做的時候,右值自己每每沒有必要保留,所以在某些狀況下能夠直接「移動」之。經過右值引用,程序能夠明確的區分出傳入的參數是否爲右值,從而避免了沒必要要的拷貝,程序的效率也就獲得了提升。咱們考慮一個簡單的數據交換的小程序,從中來體會右值引用所帶來的效率提高。咱們能夠寫一個函數swap來實現兩個變量值的交換:函數
template <class T> swap(T& a, T& b)
{
T tmp(a); // tmp對象建立後,咱們就擁有了a的兩份拷貝
a = b; // 如今咱們擁有b的兩份拷貝
b = tmp; // 如今咱們擁有a的兩份拷貝
}spa
在這段代碼中,雖然咱們只是爲了進行簡單的數據交換,可是卻執行了屢次對象拷貝。這些對象的拷貝操做,特別是當這些對象比較大的時候,無疑會影響程序的效率。
那麼,若是使用右值引用如何實現呢?.net
// 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++中的引用類型在左值右值方面的缺陷。從庫設計者的角度講,它給庫設計者又帶來了一把利器。而對於廣大的庫使用者而言,不動一兵一卒便可以得到「免費的」效率提高。htm
摘自:http://blog.csdn.net/shellching/archive/2010/04/20/5506019.aspxC++ 新特性-右值引用對象