偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

開發(fā) 前端
C++11標(biāo)準(zhǔn)對(duì)左值和右值做了更細(xì)致的劃分:左值 (Lvalue):表示內(nèi)存中的一個(gè)具體位置,可以取地址,通常是一個(gè)對(duì)象或者變量的引用。右值 (Rvalue):臨時(shí)的、不可取地址的對(duì)象,通常是表達(dá)式的結(jié)果。

首先理解下左值和右值。

C++98/03標(biāo)準(zhǔn)中:左值是指有名字的對(duì)象,右值是指臨時(shí)對(duì)象,但是我們提到的時(shí)候并不多。

C++11標(biāo)準(zhǔn)對(duì)左值和右值做了更細(xì)致的劃分:

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

右值 (Rvalue):臨時(shí)的、不可取地址的對(duì)象,通常是表達(dá)式的結(jié)果。

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

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

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

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

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

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

push_back()是std::vector容器的一個(gè)成員函數(shù),用來將一個(gè)元素添加到容器的末尾?!?/span>

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

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

然后v.push_back(str),這時(shí)候str是左值,會(huì)被拷貝?!?/p>

而如果是v.push_back(std::move(str)),或者直接push_back("hello"),這時(shí)候就是右值,觸發(fā)移動(dòng)構(gòu)造,原str的內(nèi)容被移動(dòng)到vector中,之后str就空了。

左值傳遞: 

當(dāng)調(diào)用push_back(左值)時(shí),會(huì)調(diào)用拷貝構(gòu)造函數(shù)。 

#include <iostream>
#include <vector>

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

    // 拷貝構(gòu)造函數(shù)
    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);  // 會(huì)調(diào)用拷貝構(gòu)造函數(shù)
    return 0;
}

輸出: 

MyClass(10) constructor
MyClass(10) copy constructor

在這個(gè)例子中,當(dāng)我們將obj(一個(gè)左值)傳遞給push_back()時(shí),std::vector需要復(fù)制這個(gè)對(duì)象,調(diào)用了MyClass的拷貝構(gòu)造函數(shù)?!?/span>

右值傳遞: 

當(dāng)調(diào)用push_back(右值)時(shí),會(huì)調(diào)用移動(dòng)構(gòu)造函數(shù)。 

容器可以“移動(dòng)”這個(gè)對(duì)象到內(nèi)部,而不需要進(jìn)行復(fù)制。 

這意味著會(huì)調(diào)用對(duì)象的移動(dòng)構(gòu)造函數(shù)(如果存在的話),更高效,尤其是當(dāng)對(duì)象比較大或包含大量數(shù)據(jù)時(shí)。 

#include <iostream>
#include <vector>

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

    // 移動(dòng)構(gòu)造函數(shù)
    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));  // 會(huì)調(diào)用移動(dòng)構(gòu)造函數(shù)
    return 0;
}

輸出: 

MyClass(20) constructor
MyClass(20) move constructor

在這個(gè)例子中,通過MyClass(20)創(chuàng)建了一個(gè)臨時(shí)對(duì)象,這是一個(gè)右值。當(dāng)它傳遞給push_back()時(shí),std::vector會(huì)調(diào)用移動(dòng)構(gòu)造函數(shù),而不是拷貝構(gòu)造函數(shù)。這樣,MyClass(20)的資源會(huì)被“移動(dòng)”到vec中,而不需要額外的內(nèi)存分配和復(fù)制數(shù)據(jù)?!?/span>

底層實(shí)現(xiàn)原理: 

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

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

vector的push_back有兩個(gè)重載版本:

一個(gè)是const T&,另一個(gè)是T&&。

當(dāng)傳入左值時(shí),編譯器選擇第一個(gè)版本,進(jìn)行拷貝;

當(dāng)傳入右值時(shí),選擇第二個(gè)版本,進(jìn)行移動(dòng)?!?/span>

總結(jié): 

特性

左值(push_back(a))

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

拷貝/移動(dòng)

拷貝構(gòu)造

移動(dòng)構(gòu)造

原對(duì)象狀態(tài)

保留原值

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

性能

可能較慢(深拷貝)

通常更快(僅僅轉(zhuǎn)移資源)

適用對(duì)象

需要保留的具名對(duì)象

臨時(shí)對(duì)象或者不再需要的對(duì)象

 

責(zé)任編輯:武曉燕 來源: CppPlayer
相關(guān)推薦

2022-02-16 12:52:22

C++項(xiàng)目編譯器

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++函數(shù)

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數(shù)據(jù)庫MySQL

2016-03-21 10:40:53

RDDSpark SQL數(shù)據(jù)集

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++表達(dá)式右值

2017-11-21 22:49:10

2022-09-03 08:03:14

UbuntuDebian
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)