1. 程式人生 > >c++ 特性: 右值引用與移動語義

c++ 特性: 右值引用與移動語義

c++11中引入了右值引用。

左值與右值

先區分左值與右值,這裡參考c++ 右值引用中對左值和右值區分方法:
左值和右值都是針對表示式,左值是指表示式結束後依然存在的持久物件,右值是指表示式結束時就不再存在的臨時物件。
一個區分左值和右值的簡便方法是:看能不能對錶達式進行取地址。如果能,則為左值;如果不能,則為右值。

int a, b;
int* pFlag = &a;
vector<int> vcTemp;
string("hello");
const int &m=1;

a 、b 是持久物件(可以對它取地址),為左值
a+b 返回一個臨時物件,非持久物件(不可取地址),為右值
a++ 先拷貝a變數,然後對a自增,接著返回拷貝的臨時變數,為右值
++a 對a自增,然後返回a本身,為左值
pFlag、*pFlag 都是持久物件,為左值
vcTemp[0] 過載[] 操作符,返回int& ,為持久物件,為左值。
100、string(“hello”) 都是臨時物件,為右值
m 是常量引用,引用到一個右值,但引用本身是一個持久物件,故為左值。

一般的情況開銷

在不使用右值引用時,程式在執行過程中產生和銷燬臨時變數會浪費資源,而右值引用,就相當於“竊取”了臨時變數的儲存地址為己用。語法是 &&

#include<iostream>
#include<utility>
using namespace std;

class A
{
    int i;
    public:    
    void play()
    {
        ++i;
    }
    ~A()
    {
        cout<<"I am out"<<endl;
    }
};

A fun()
{
    A a;
    a.play();
    //return move(a);
return a; } int main() { A b = fun(); }

每個編譯器都有自己的優化,MinGW中,輸出:

I am out

這隻有輸出一次,說明只建立了一次A物件,是最好的情況。
但是在VC14++中:

I am out
I am out

輸出了兩次,說明,即使有些編譯器有優化,但是臨時變數的開銷依然是存在的。

移動建構函式和移動賦值運算

Talk is cheap. Let me show the code. : )

#include<iostream>
#include<utility>
#include<cstring> using namespace std; class A { public: char* pData; A() {} //複製建構函式 A(const A& a) { pData = new char[strlen(a.pData)+1]; strcpy(pData, a.pData); } //移動建構函式 A(A&& a) { pData = a.pData; a.pData = nullptr; } ~A() { if(pData!=nullptr) { delete[] pData; pData = nullptr; //這是個好習慣 } } //賦值運算 A& operator= (const A& a) { pData = new char[strlen(a.pData)+1]; strcpy(pData, a.pData); return *this; } //移動賦值運算 A& operator= (A&& a) { pData = a.pData; a.pData = nullptr; return *this; } void play() { if(pData!=nullptr) cout<<pData; cout<<endl; } }; int main() { A a; a.pData = new char[10] { '1','2','3','4','5','6','7','8','9','\0' }; A b = move(a); cout<<"a: "; a.play(); cout<<"b: "; b.play(); }

輸出:

a:
b: 123456789

相關推薦

c++ 特性 引用移動語義

c++11中引入了右值引用。 左值與右值 先區分左值與右值,這裡參考c++ 右值引用中對左值和右值區分方法: 左值和右值都是針對表示式,左值是指表示式結束後依然存在的持久物件,右值是指表示式結束時就不再存在的臨時物件。 一個區分左值和右值的簡便方法是

C++11引用移動語意完美轉發

在C++11之前我們很少聽說左值、右值這個叫法,自從C++11支援了右值引用之後,大多數人會像我一樣疑惑:啥是右值? 準確的來說: 左值:擁有可辨識的記憶體地址的識別符號便是一個左值。 右值:非左值。 左值引用:左值識別符號的一個別名,簡稱引用

C++ 面試 C++ 11 新特性引用移動

右值引用 什麼是左值,什麼是右值,簡單說左值可以賦值,右值不可以賦值。以下面程式碼為例,“ A a = getA();”該語句中a是左值,getA()的返回值是右值。 #include <iostream> class A { public

C++11之引用移動構造

添加 oooo 返回對象 oat 值引用 apc 定義 tco pri ----------------------------右值引用--------------------------------- 右值定義:   通俗來講,賦值號左邊的就是左值,賦值號右邊的就

C++11執行緒指南(4)--引用移動語義

1. 按值傳遞   什麼是按值傳遞?   當一個函式通過值的方式獲取它的引數時,就會包含一個拷貝的動作。編譯器知道如何去進行拷貝。如果引數是自定義型別,則我們還需要提供拷貝建構函式,或者賦值運算子來進行深拷貝。然而,拷貝是需要代價的。在我們使用STL容器時,就存在大量的拷貝

C++ 引用移動操作

銷毀 帶來 臨時對象 類型 左值引用 都是 獲得 留下 c++11 右值引用和移動操作是C++11提出的新概念,通過這些操作,可以降低拷貝操作帶來的消耗。先來簡單介紹一下左值和右值。 左值一般指的是一個對象,或者說是一個持久的值,例如賦值的返回值、下標操作、解引用以及前置遞

C++11 標準新特性: 引用轉移語義

https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 特性的目的 右值引用 (Rvalue Referene) 是 C++ 新標準 (C++11, 11 代表 2011 年 ) 中引入的新特性

C++的雜七雜八我家的返回才不可能這麼傲嬌(引用移動語義

大凡程式語言,都會有“函式”這個概念。而對於外部而言,一個函式最重要的部分就是它的返回值了。 說這裡,返回值其實應該是一個很簡單的話題。當需要通過函式傳遞一個值出去的時候,使用返回值不是理所當然的嘛,比如說,像下面這樣: int add(int a, int b)

C++11引用引用

C++11:左值引用與右值引用 在 C++11 的新標準中,出現了「右值引用」的說法,既然有了右值引用,那麼傳統的引用也就叫做左值引用。 右值引用 (Rvalue Referene) 是 C++ 新標準 (C++11, 11 代表 2011 年 ) 中引入的新特性 , 它實現了轉

C++11特性--引用移動語義,強制移動move()

1.右值引用   *右值:不能對其應用地址運算子的值。   *將右值關聯到右值引用導致該右值被儲存到特定的位置,且可以獲取該位置的地址   *右值包括字面常量(C風格字串除外,它表示地址),諸如X+Y等表示式以及返回值得函式(條件是該函式返回的不是引用)   *引入右值引用的主要目的之一是實行移動語義   E

引用移動建構函式的一點理解

說明:右值引用是c++11中的新特性,本來c++中是有一個左值引用的,引入右值引用後,多了很多概念,再看prime的時候,就覺得似乎讓c++更繁瑣了。偶然在知乎上看到這個話題,於是有了一點理解,遂記錄於此。知乎連結 大象與冰箱 我們還是從大象與冰箱的

C++引用移動語義淺說

1、神馬叫右值和右值引用C++中所有的值分兩種,一種叫左值(可以取地址,有名字的),一種叫右值(不可以取地址,沒有名字的)。常見的如 int a  = b+c ;表示式中a  可以取地址為左值,(b+c

引用移動語義

1.左值與右值 左值的幾種定義 a.可以取地址的,有名字的就是左值(但const常量不能做為左值) b.左值則是有名稱的,能夠被操作的物件 c.在記憶體中有獨立的記憶體空間,並且記憶體空間的內容是可變的,也就是通常所說的變數 右值的幾種定義 a.不能直接取地址,沒有名稱的,

引用move語義

右值 C語言中,左值(left value, lvalue)只出現在賦值符左邊的量,右值(right value, rvalue)是出現在賦值符右邊的量。在C++中,右值的定義稍微不同,每一個表示式都會產生一個左值或者右值,所以表示式也稱左值表示式或右值表示式

c++11物件移動 & 引用 & 移動建構函式

一、概述 c++ 11 新標準中最主要的特徵是可以移動而非拷貝物件的能力。很多情況下,物件拷貝後就會立即被銷燬。 在這些情況下,移動而非拷貝物件會大幅度提升效能。 在舊 C++ 標準中,沒有直接的方法移動物件。因此,即使不必要拷貝物件的情況下,我們也不得不拷貝。如果物件本身要求

C++0x漫談》系列之引用(或“move語意完美轉發”)(下)

《C++0x漫談》系列之:右值引用 或“move語意與完美轉發”(下) By 劉未鵬(pongba) 《C++0x漫談》系列導言 這個系列其實早就想寫了,斷斷續續關注C++0x也大約有兩年餘了,其間看著各個重要proposals一路review過來:rvalue-r

C++11新特性引用

什麼是左值,什麼是右值? An l-value expression refers to an object's identity, whereas a r-value expression refers to an object's value. 左值標識物件的身份,右值標識物件的值(我把它理解為被物

C++11 新特性引用和轉移建構函式

問題背景 #include <iostream> usingnamespace std;   vector<int> doubleValues (const vector<int>& v)   {  

C++11嚐鮮引用和轉發型引用

右值引用 為了解決移動語義及完美轉發問題,C++11標準引入了右值引用(rvalue reference)這一重要的新概念。右值引用採用T&&這一語法形式,比傳統的引用T&(如今被稱作左值引用 lvalue reference)多一個&。

C++11特性引用

wap 移動語義 ostream 更改 let 強制轉換 生命期 不能 size title: 右值引用與移動語義 date: 2019-2-24 15:06:34 tags: 學習 categories: 日常 --- 什麽是右值?在C++中,一種被廣泛認可的說法是,不