最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11的右值引用的具體使用

 更新時間:2020年02月18日 09:24:34   作者:行者孫  
這篇文章主要介紹了C++11的右值引用的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

C++11 引入了 std::move 語義、右值引用、移動構(gòu)造和完美轉(zhuǎn)發(fā)這些特性。由于這部分篇幅比較長,分為3篇來進行闡述。

在了解這些特性之前,我們先來引入一些問題。

一、問題導(dǎo)入

  1. 函數(shù)返回值是傳值的時候發(fā)生幾次對象構(gòu)造、幾次拷貝?
  2. 函數(shù)的形參是值傳遞的時候發(fā)生幾次對象構(gòu)造?

讓我們先來看一段代碼,

// main.cpp
#include <iostream>
using namespace std;

class A{
public:
  A(){
   cout<<"class A construct!"<<endl;
  } 
  A(const A&){
   cout<<"class A copy!"<<endl;
  }
  A& operator=(const A&){
   cout<<"assignment called!"<<endl;
  }
  ~A(){
   cout<<"class A destruct!"<<endl;
  }
};

A get_A_value(){
  return A();
}
int main(){
  A a = get_A_value();
  return 0;
}

使用 g++ 編譯;注意使用 -fno-elide-constructors關(guān)閉省略構(gòu)造優(yōu)化

g++ main.cpp -fno-elide-constructors

可以得到以下輸出

class A construct!
class A destruct!
class A copy!
class A destruct!
class A destruct!

可以看到A a=get_A_value(); 一行代碼居然產(chǎn)生1次對象構(gòu)造和2次對象的拷貝構(gòu)造!具體為

  • 在 get_A_value() 里 A() 構(gòu)造了臨時對象,發(fā)生了一次構(gòu)造;
  • 函數(shù)返回的時候會把臨時對象拷貝后作為返回值,發(fā)生一次拷貝;
  • A a = 函數(shù)返回值發(fā)生了拷貝構(gòu)造。

如果使用編譯器優(yōu)化(默認), 則會把臨時對象拷貝的那次 和 用返回值構(gòu)造最終對象的拷貝的給省略了;也即,只有一次拷貝和析構(gòu)。

class A construct!
class A destruct!

如果把上面代碼改一下

// ... A

void pass_A_by_value(A a){

}
int main(){
  A a;
  pass_A_by_value(a);
  return 0;
}

在去掉優(yōu)化 g++ main.cpp -fno-elide-constructors時輸出為

class A construct!
class A copy!
class A destruct!
class A destruct!

1次構(gòu)造加上1次拷貝。

因此,下次如果面試的時候有人問這個問題,你就可以說:默認情況下經(jīng)過編譯器優(yōu)化后臨時對象的拷貝就會被省去,如果使用 -fno-elide-constructors 省略優(yōu)化,則還要考慮臨時對象的拷貝。

事實上,在未經(jīng)優(yōu)化的情況下,以下時候拷貝構(gòu)造函數(shù)會被調(diào)用:

  1. 函數(shù)內(nèi)的局部對象做為返回值返回(不是引用)的時候會發(fā)生拷貝(拷貝為臨時對象返回)
  2. 函數(shù)形參為傳值的時候,會發(fā)生拷貝構(gòu)造
  3. 一個對象以另外一個對象進行初始化的時候

對象的頻繁構(gòu)造是程序的開銷,特別是當對象內(nèi)部有堆上內(nèi)存(比如有 new 出來的成員)的時候,每次拷貝構(gòu)造的時候都需要用 new 申請一塊內(nèi)存,造成性能的降低。對于情況2,好習慣是如果函數(shù)參數(shù)是只讀的(也即不會在程序內(nèi)進行修改),傳引用作為參數(shù),也即 pass_A_by_refrence(const A &a); 對于情況1,編譯器會為我們進行優(yōu)化; 對于情況3,C++11 引入了一種移動構(gòu)造函數(shù)的概念,它將獲取**右值引用*,右值的“資源” move 到新對象中,這個過程中不會申請新的內(nèi)存,從而達到提高了效率和性能。

所以,要理解些關(guān)鍵詞 “移動構(gòu)造”、“移動語義” ,首先要理解右值和右值引用。

二、右值和右值引用

2.1 左值(lvalue)和右值(rvalue)

在 一、問題導(dǎo)入 里我們提到了臨時對象,也即函數(shù)返回值的時候只會“臨時”存在的對象(運行超過那一行就會結(jié)束它的生存期),這個臨時返回值就是一個右值;
右值的最直觀的定義為,顧名思義:

位于賦值運算符 = 右邊的值,為右值;在左邊的則為左值

A a = foo(); // foo() 為右值
char *x = "thu"; // “thu”為字面值也為右值
a = b + c; // b + c這個結(jié)果也是一個右值

在C++中,還有個定義為:

左值可以取得地址、有名字; 不可以取得地址、沒有名字的為右值。

所以 A a = foo()可以用 &a取得a的地址,a 是左值,然是不能取得 foo()的地址,(&foo())無法通過編譯, foo()返回的臨時對象也是沒有名字的,所以是右值。

在C++11中,右值包括兩種,一中是將亡值(xvalue, eXpiring Value),一種是純右值(prvalue,Pure Rvalue)[1]。函數(shù)非引用返回的臨時對象、運算表達式的結(jié)果、1, 3.14,'c'這樣的字面值等都屬于純右值。而xvalue則是由 C++11引入的 如返回值為 A&& 的函數(shù)返回值或者std::move()的返回值等。

不深究的話,我們只需要知道左值和右值的區(qū)別就行了。對于右值的詳細分類則不必深究。

2.2 左值引用和右值引用

左值引用就是一般的引用,一般用一個&表示,例如

const A &a_ref = a; // 取得對象 a 的引用

左值引用相當于別名,指向一個具體的對象。

右值引用

右值引用顧名思義,就是右值的引用, 用 &&表示;
A &&r_ref = getRvalue(); // r_ref 是一個右值引用
右值引用也相當于別名,與左值的區(qū)別為右值引用是無名變量的別名。

getRvalue() 是一個返回右值的函數(shù),右值在這一句執(zhí)行完就該結(jié)束他的生存期了,如果是對象就該調(diào)用析構(gòu)函數(shù)了;但是==右值引用讓它強行續(xù)命==;使用右值引用指向右值,右值的生存期和右值引用一樣長了,這也就少一次對象的析構(gòu)和構(gòu)造了。

C++的右值引用主要有兩個用處,一個是移動語義,一個是完美轉(zhuǎn)發(fā)。這個將在接下來的兩篇來講。

總結(jié)

為了導(dǎo)入右值和移動語義,首先復(fù)習了以下臨時對象在函數(shù)返回值和傳參數(shù)時構(gòu)造了幾次;然后對比介紹了左值和右值,以及右值引用的形式和含義。為移動語義和完美轉(zhuǎn)發(fā)的介紹做鋪墊。

參考資料

Michale Wang| IBM XL 編譯器中國 《深入理解C++11》, 機械工業(yè)出版社

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Trae+Qt+MSVC環(huán)境配置的實現(xiàn)示例

    Trae+Qt+MSVC環(huán)境配置的實現(xiàn)示例

    本文主要介紹了Trae+Qt+MSVC環(huán)境配置,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-03-03
  • c語言冒泡排序法代碼

    c語言冒泡排序法代碼

    c語言冒泡排序法代碼,這個是大家最早接觸的算法吧,總在寫 總在錯,學習就是這么個過程, 溫故才知新, 望自己謹記
    2013-02-02
  • C++語言設(shè)計實現(xiàn)五子棋

    C++語言設(shè)計實現(xiàn)五子棋

    這篇文章主要為大家詳細介紹了C++語言設(shè)計實現(xiàn)五子棋,包括數(shù)據(jù)結(jié)構(gòu)和對象設(shè)計及主函數(shù)調(diào)用實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • 詳解設(shè)計模式中的中介者模式在C++編程中的運用

    詳解設(shè)計模式中的中介者模式在C++編程中的運用

    這篇文章主要介紹了設(shè)計模式中的中介者模式在C++編程中的運用,中介者模式將對象間的通信封裝到一個類中,將多對多的通信轉(zhuǎn)化為一對多的通信,降低了系統(tǒng)的復(fù)雜性,需要的朋友可以參考下
    2016-03-03
  • 詳解C++異常處理三個重要組成部分

    詳解C++異常處理三個重要組成部分

    這篇文章主要為大家介紹了C++異常處理的三個重要組成部分示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • C語言標準時間與秒單位相互轉(zhuǎn)換

    C語言標準時間與秒單位相互轉(zhuǎn)換

    這篇文章主要介紹了C語言標準時間與秒單位相互轉(zhuǎn)換,秒單位與標準時間的轉(zhuǎn)換方式,這份代碼一般用在嵌入式單片機里比較多,比如:設(shè)置RTC時鐘的時間,從RTC里讀取秒單位時間后,需要轉(zhuǎn)換成標準時間顯示。下文分享需要的小伙伴可以參考一下
    2022-05-05
  • C++詳細講解函數(shù)調(diào)用與Struct和CLass的區(qū)別

    C++詳細講解函數(shù)調(diào)用與Struct和CLass的區(qū)別

    主調(diào)函數(shù)使用被調(diào)函數(shù)的功能,稱為函數(shù)調(diào)用。在C語言/C++中,只有在函數(shù)調(diào)用時,函數(shù)體中定義的功能才會被執(zhí)行,下面讓我們詳細來了解
    2022-05-05
  • 在C語言中比較兩個字符串是否相等的方法

    在C語言中比較兩個字符串是否相等的方法

    這篇文章主要介紹了在C語言中比較兩個字符串是否相等的方法,分別介紹了strcmp()函數(shù)和strcasecmp()函數(shù),注意功能區(qū)分,需要的朋友可以參考下
    2015-08-08
  • 詳解C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)

    詳解C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)

    這篇文章主要為大家介紹了C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • C++ STL 四種智能指針的用法詳解

    C++ STL 四種智能指針的用法詳解

    C++ 標準模板庫 STL(Standard Template Library) 一共給我們提供了四種智能指針:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,今天給大家詳細介紹這幾種指針的具體用法,需要的朋友參考下吧
    2021-06-06

最新評論

方正县| 沙田区| 若尔盖县| 武城县| 潮州市| 漳浦县| 新昌县| 九江市| 阜宁县| 枞阳县| 阿尔山市| 兴安盟| 临夏县| 视频| 阿瓦提县| 永德县| 柞水县| 邛崃市| 黎川县| 新巴尔虎左旗| 融水| 河池市| 厦门市| 精河县| 周口市| 长治县| 新乐市| 广东省| 克拉玛依市| 丰都县| 澳门| 特克斯县| 万州区| 行唐县| 淅川县| 曲靖市| 文水县| 浦城县| 扶沟县| 云阳县| 黄平县|