成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++ push_back()左值和右值的區別是什么?

開發 前端
C++11標準對左值和右值做了更細致的劃分:左值 (Lvalue):表示內存中的一個具體位置,可以取地址,通常是一個對象或者變量的引用。右值 (Rvalue):臨時的、不可取地址的對象,通常是表達式的結果。

首先理解下左值和右值。

C++98/03標準中:左值是指有名字的對象,右值是指臨時對象,但是我們提到的時候并不多。

C++11標準對左值和右值做了更細致的劃分:

左值 (Lvalue):表示內存中的一個具體位置,可以取地址,通常是一個對象或者變量的引用。

右值 (Rvalue):臨時的、不可取地址的對象,通常是表達式的結果。

將亡值(xvalue, expiring value):一種特殊的右值,表示將要銷毀的對象(如std::move()返回的對象)

int&& r = std::move(x);  // std::move(x) 是將亡值

純右值(prvalue, pure rvalue):臨時值,表示一個臨時的對象或常量,如字面量、函數返回值等。

int&& r = 10;       // 10 是純右值(臨時對象)

類左值:類左值是一個統稱,涵蓋了左值(lvalue)和將亡值(xvalue)。它們表示可以引用的對象。類左值包括了所有能夠通過&或&&引用的值,無論是左值還是將亡值。

int x = 10;
int& r = x;  // x 是類左值(glvalue)
int&& r2 = std::move(x);  // std::move(x) 是將亡值(xvalue)

push_back()是std::vector容器的一個成員函數,用來將一個元素添加到容器的末尾。 

C++11之前,push_back()只有接受const左值引用的版本,所以無論是左值還是右值都會被拷貝到vector中。但C++11引入了移動語義,這時候有了右值引用的重載版本。

如果有std::string str = "hello"; 

然后v.push_back(str),這時候str是左值,會被拷貝。 

而如果是v.push_back(std::move(str)),或者直接push_back("hello"),這時候就是右值,觸發移動構造,原str的內容被移動到vector中,之后str就空了。

左值傳遞: 

調用push_back(左值)時,會調用拷貝構造函數。 

#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass(int value) : value(value) {
        std::cout << "MyClass(" << value << ") constructor\n";
    }

    // 拷貝構造函數
    MyClass(const MyClass& other) : value(other.value) {
        std::cout << "MyClass(" << value << ") copy constructor\n";
    }

private:
    int value;
};

int main() {
    std::vector<MyClass> vec;
    MyClass obj(10);
    // 左值傳遞
    vec.push_back(obj);  // 會調用拷貝構造函數
    return 0;
}

輸出: 

MyClass(10) constructor
MyClass(10) copy constructor

在這個例子中,當我們將obj(一個左值)傳遞給push_back()時,std::vector需要復制這個對象,調用了MyClass的拷貝構造函數。 

右值傳遞: 

調用push_back(右值)時,會調用移動構造函數。 

容器可以“移動”這個對象到內部,而不需要進行復制。 

這意味著會調用對象的移動構造函數(如果存在的話),更高效,尤其是當對象比較大或包含大量數據時。 

#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass(int value) : value(value) {
        std::cout << "MyClass(" << value << ") constructor\n";
    }

    // 移動構造函數
    MyClass(MyClass&& other) noexcept : value(other.value) {
        std::cout << "MyClass(" << value << ") move constructor\n";
    }

private:
    int value;
};

int main() {
    std::vector<MyClass> vec;

    // 右值傳遞
    vec.push_back(MyClass(20));  // 會調用移動構造函數
    return 0;
}

輸出: 

MyClass(20) constructor
MyClass(20) move constructor

在這個例子中,通過MyClass(20)創建了一個臨時對象,這是一個右值。當它傳遞給push_back()時,std::vector會調用移動構造函數,而不是拷貝構造函數。這樣,MyClass(20)的資源會被“移動”到vec中,而不需要額外的內存分配和復制數據。 

底層實現原理: 

std::vector 的 push_back() 提供兩個重載版本: 

void push_back(const T& val);  // 左值版本:拷貝
void push_back(T&& val);       // 右值版本:移動(C++11 新增)

vector的push_back有兩個重載版本:

一個是const T&,另一個是T&&。

當傳入左值時,編譯器選擇第一個版本,進行拷貝;

當傳入右值時,選擇第二個版本,進行移動。 

總結: 

特性

左值(push_back(a))

右值(push_back(std::move(a)))

拷貝/移動

拷貝構造

移動構造

原對象狀態

保留原值

有效但未定義(通常為空)

性能

可能較慢(深拷貝)

通常更快(僅僅轉移資源)

適用對象

需要保留的具名對象

臨時對象或者不再需要的對象

 

責任編輯:武曉燕 來源: CppPlayer
相關推薦

2022-02-16 12:52:22

C++項目編譯器

2025-03-10 08:30:00

2022-03-11 07:59:09

容器代碼元素

2010-02-03 17:32:54

C++左值與右值

2012-02-13 10:18:42

C++ 11

2022-07-26 00:36:06

C#C++函數

2025-05-08 08:05:00

C++代碼編程

2022-11-15 10:03:34

2023-10-23 11:07:37

HTTPRPC

2021-03-15 14:00:56

PythonC語言編程語言

2025-06-03 10:10:00

C++左值右值

2025-02-06 08:44:11

MySQLEXISTSIN

2024-12-30 07:20:00

Redis數據庫MySQL

2016-03-21 10:40:53

RDDSpark SQL數據集

2015-02-26 10:29:41

Google百度

2018-05-21 21:26:59

Apache HiveHbaseSQL

2021-10-27 08:54:11

Pythonencodeencoding

2025-06-06 07:35:06

C++表達式右值

2017-11-21 22:49:10

2022-09-03 08:03:14

UbuntuDebian
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费国产网站 | 中文av电影| 中文字幕在线看人 | 成人福利视频网站 | 久久国产激情视频 | 黄色网址在线免费观看 | 国产福利91精品 | 狠狠躁天天躁夜夜躁婷婷老牛影视 | 九九亚洲| 91传媒在线观看 | 老司机精品福利视频 | 国产日韩欧美在线观看 | 男女性毛片| 毛片黄片免费看 | 免费成人高清在线视频 | 在线观看成人免费视频 | 欧美日韩在线免费观看 | 欧美精品一区在线发布 | 国产午夜精品一区二区三区四区 | 艹逼网 | 国产超碰人人爽人人做人人爱 | 国产成人免费 | 麻豆一区| 亚洲成人免费视频在线 | 国产精品高清在线 | 久草中文网 | 久久久久久成人网 | 蜜桃视频在线观看免费视频网站www | 久久一热 | 夜夜摸夜夜操 | 一级做a爰片性色毛片16美国 | 日本天天操 | 国产精品免费观看视频 | 中文在线播放 | 91精品国产91久久久久久丝袜 | 亚洲成人精选 | 99在线免费观看视频 | 国产亚洲精品精品国产亚洲综合 | 日本不卡一区 | 欧美一区二区在线播放 | 好好的日在线视频 |