C++ 新特性-右值引用

做爲最重要的一項語言特性,右值引用(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++ 新特性-右值引用對象

相關文章
相關標籤/搜索