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

c++ 移動賦值/移動構(gòu)造函數(shù)的實現(xiàn)

 更新時間:2026年03月27日 09:18:27   作者:.select.  
這篇文章主要介紹了c++ 移動賦值/移動構(gòu)造函數(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在 C++11 引入移動語義(Move Semantics)之前,對象之間的賦值或初始化通常涉及深拷貝(Deep Copy),即復(fù)制所有數(shù)據(jù)。這對于包含動態(tài)分配資源(如 std::vectorstd::string, 原始指針管理的內(nèi)存)的對象來說,開銷很大。

移動構(gòu)造函數(shù)移動賦值運算符允許我們將資源的“所有權(quán)”從一個對象轉(zhuǎn)移到另一個對象,而不是復(fù)制數(shù)據(jù)。這極大地提高了性能,特別是對于臨時對象(右值)。

1. 核心概念:左值 vs 右值

理解移動語義的前提是區(qū)分左值(lvalue)和右值(rvalue):

  • 左值:有名字、有持久地址的對象(如 int a = 10; 中的 a)。
  • 右值:通常是臨時對象、字面量或即將銷毀的對象(如 a + b 的結(jié)果,或者函數(shù)返回的非引用對象)。

移動語義的核心思想是:既然右值(臨時對象)馬上就要銷毀了,我們沒必要復(fù)制它的資源,直接“偷”過來用就行了。

2. 移動構(gòu)造函數(shù) (Move Constructor)

定義:當(dāng)一個新對象被一個右值初始化時調(diào)用。
簽名ClassName(ClassName&& other)
參數(shù):接受一個右值引用(T&&)。

作用

將源對象(other)的資源指針直接轉(zhuǎn)移給新對象,并將源對象的指針置為 nullptr(或其他安全狀態(tài)),防止析構(gòu)時重復(fù)釋放內(nèi)存。

代碼示例

class MyVector {
private:
    int* data;
    size_t size;
public:
    // 構(gòu)造函數(shù)
    MyVector(size_t s) : size(s) {
        data = new int[s];
        std::cout << "構(gòu)造: 分配內(nèi)存\n";
    }
    // 拷貝構(gòu)造函數(shù) (深拷貝)
    MyVector(const MyVector& other) : size(other.size) {
        data = new int[size];
        std::copy(other.data, other.data + size, data);
        std::cout << "拷貝構(gòu)造: 深拷貝內(nèi)存\n";
    }
    // --- 移動構(gòu)造函數(shù) ---
    MyVector(MyVector&& other) noexcept 
        : data(other.data), size(other.size) {
        // 關(guān)鍵步驟:竊取指針
        other.data = nullptr; // 將源對象置為空,防止其析構(gòu)時釋放這塊內(nèi)存
        other.size = 0;
        std::cout << "移動構(gòu)造: 轉(zhuǎn)移所有權(quán)\n";
    }
    // 析構(gòu)函數(shù)
    ~MyVector() {
        if (data) {
            delete[] data;
            std::cout << "析構(gòu): 釋放內(nèi)存\n";
        }
    }
};
// 使用場景
MyVector createVector() {
    MyVector temp(100);
    return temp; // 返回臨時對象(右值)
}
int main() {
    // 這里會觸發(fā)移動構(gòu)造函數(shù),而不是拷貝構(gòu)造
    MyVector v = createVector(); 
    return 0;
}

3. 移動賦值運算符 (Move Assignment Operator)

定義:當(dāng)一個已存在的對象被賦予一個右值時調(diào)用。
簽名ClassName& operator=(ClassName&& other)
返回值:通常返回 *this 以支持鏈?zhǔn)劫x值。

作用

  1. 自賦值檢查:防止 a = std::move(a) 導(dǎo)致錯誤。
  2. 清理舊資源:釋放當(dāng)前對象持有的舊資源。
  3. 竊取新資源:接管源對象的資源。
  4. 重置源對象:將源對象置于有效但未指定的狀態(tài)(通常指針置空)。

代碼示例

class MyVector {
    // ... (同上) ...
public:
    // --- 移動賦值運算符 ---
    MyVector& operator=(MyVector&& other) noexcept {
        if (this != &other) { // 1. 自賦值檢查
            // 2. 釋放當(dāng)前資源
            delete[] data;
            // 3. 竊取資源
            data = other.data;
            size = other.size;
            // 4. 重置源對象
            other.data = nullptr;
            other.size = 0;
        }
        std::cout << "移動賦值: 轉(zhuǎn)移所有權(quán)\n";
        return *this;
    }
};
int main() {
    MyVector v1(10);
    MyVector v2(20);
    // std::move 將左值 v1 強制轉(zhuǎn)換為右值引用,觸發(fā)移動賦值
    v2 = std::move(v1); 
    // 此時 v1 內(nèi)部指針為 null,v2 擁有了原本 v1 的內(nèi)存
    return 0;
}

4. 關(guān)鍵細節(jié)與最佳實踐

A.noexcept的重要性

移動構(gòu)造函數(shù)和移動賦值運算符必須標(biāo)記為 noexcept(除非你真的可能拋出異常)。

  • 原因:標(biāo)準(zhǔn)庫容器(如 std::vector)在擴容重新分配內(nèi)存時,如果元素的移動操作是 noexcept 的,它會優(yōu)先使用移動;否則,為了保證異常安全(如果移動中途失敗,原數(shù)據(jù)還在),它只能退回到拷貝。
  • 如果不加 noexcept,std::vector<MyVector> 的性能可能會退化回拷貝語義。

B.std::move是什么?

std::move 不移動任何東西。它只是一個強制類型轉(zhuǎn)換工具,將左值轉(zhuǎn)換為右值引用(T&&),從而告訴編譯器:“這個對象我可以被移動,請調(diào)用移動版本的操作”。

  • 調(diào)用 std::move(x) 后,x 處于有效但未指定的狀態(tài)。除了銷毀或重新賦值外,不應(yīng)再使用 x 的值。

C. 規(guī)則之五 (Rule of Five)

如果你需要自定義以下五個函數(shù)中的任何一個,通常意味著你需要自定義全部五個:

  1. 析構(gòu)函數(shù)
  2. 拷貝構(gòu)造函數(shù)
  3. 拷貝賦值運算符
  4. 移動構(gòu)造函數(shù)
  5. 移動賦值運算符

如果你只定義了移動操作而沒有定義拷貝操作,編譯器會自動刪除默認的拷貝構(gòu)造和拷貝賦值函數(shù)(因為資源已經(jīng)被移走了,默認拷貝是不安全的)。

D. 成員變量的自動移動

如果你的類成員變量本身支持移動語義(如 std::unique_ptrstd::vectorstd::string),你可以使用 default 讓編譯器自動生成高效的移動操作:

class MyClass {
    std::vector<int> vec;
    std::string name;
    // 編譯器自動生成的移動構(gòu)造/賦值會分別調(diào)用 vec 和 name 的移動操作
    // 非常高效且安全
    MyClass(MyClass&&) = default; 
    MyClass& operator=(MyClass&&) = default;
};

總結(jié)對比

特性拷貝構(gòu)造/賦值移動構(gòu)造/賦值
參數(shù)類型const T& (左值引用)T&& (右值引用)
行為深度復(fù)制數(shù)據(jù) (Deep Copy)轉(zhuǎn)移資源所有權(quán) (Steal Pointers)
源對象狀態(tài)保持不變變?yōu)橛行У粗付顟B(tài) (通常為空)
性能較慢 (涉及內(nèi)存分配和復(fù)制)極快 (僅指針賦值)
適用場景需要保留源對象數(shù)據(jù)時源對象是臨時值或不再需要時

到此這篇關(guān)于c++ 移動賦值/移動構(gòu)造函數(shù)的實現(xiàn)的文章就介紹到這了,更多相關(guān)c++ 移動賦值/移動構(gòu)造內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)查詢本機信息的示例代碼

    C++實現(xiàn)查詢本機信息的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C++實現(xiàn)查詢本機信息,并且進行上報,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的可以了解一下
    2023-05-05
  • C++超集C++/CLI模塊的基本類型

    C++超集C++/CLI模塊的基本類型

    這篇文章介紹了C++超集C++/CLI模塊的基本類型,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • C++發(fā)郵件簡單實例詳解

    C++發(fā)郵件簡單實例詳解

    這篇文章主要為大家詳細介紹了C++發(fā)郵件的簡單實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • OpenCV利用高斯模糊實現(xiàn)簡單的磨皮美顏效果

    OpenCV利用高斯模糊實現(xiàn)簡單的磨皮美顏效果

    這篇文章主要介紹了通過OpenCV中的高斯模糊以及雙邊模糊來實現(xiàn)一個簡單的磨皮美顏效果,文中的講解很詳細,感興趣的同學(xué)可以學(xué)習(xí)一下
    2021-12-12
  • C++中inet_pton、inet_ntop函數(shù)的用法

    C++中inet_pton、inet_ntop函數(shù)的用法

    這篇文章主要介紹了C++中inet_pton、inet_ntop函數(shù)的用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 關(guān)于C++中由于字節(jié)對齊引起內(nèi)存問題定位分析

    關(guān)于C++中由于字節(jié)對齊引起內(nèi)存問題定位分析

    前幾天遇到一個稀奇古怪的問題,在創(chuàng)建對象的時候程序異常退出,查找代碼發(fā)現(xiàn)結(jié)構(gòu)體數(shù)組問題,最終把問題簡化得到解決方法,下面小編把我的問題及解決方案分享到腳本之家平臺供大家參考下
    2021-06-06
  • C語言接口與實現(xiàn)方法實例詳解

    C語言接口與實現(xiàn)方法實例詳解

    這篇文章主要介紹了C語言接口與實現(xiàn)方法,包括接口的概念、實現(xiàn)方法及抽象數(shù)據(jù)類型等,并配合實例予以說明,需要的朋友可以參考下
    2014-09-09
  • C語言用數(shù)組實現(xiàn)反彈球消磚塊

    C語言用數(shù)組實現(xiàn)反彈球消磚塊

    這篇文章主要為大家詳細介紹了C語言用數(shù)組實現(xiàn)反彈球消磚塊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言近萬字為你講透樹與二叉樹

    C語言近萬字為你講透樹與二叉樹

    樹是計算機算法最重要的非線性結(jié)構(gòu)。因為樹能很好地描述結(jié)構(gòu)的分支關(guān)系和層次特性,所以在計算機科學(xué)和計算機應(yīng)用領(lǐng)域有著廣泛的應(yīng)用。這篇文章我就帶大家一起了解一下樹、二叉樹這種結(jié)構(gòu),下篇文章會重點向大家介紹二叉樹的遍歷算法
    2022-05-05
  • C++ OpenCV實現(xiàn)像素畫的示例代碼

    C++ OpenCV實現(xiàn)像素畫的示例代碼

    這篇文章主要介紹了通過OpenCV進行圖片像素的變化,從而形成像素畫效果的功能。文中的示例代碼講解詳細,感興趣的小伙伴可以動手試一試
    2022-01-01

最新評論

明水县| 宝山区| 余干县| 华阴市| 柏乡县| 金乡县| 南乐县| 平远县| 安顺市| 威远县| 张掖市| 崇阳县| 阿拉善左旗| 宁夏| 宣城市| 淮阳县| 额济纳旗| 饶阳县| 巩义市| 长宁区| 安阳市| 香港 | 汶川县| 和田市| 四会市| 龙井市| 墨玉县| 祁东县| 池州市| 迁安市| 隆昌县| 乌拉特前旗| 齐齐哈尔市| 西城区| 拜泉县| 黔江区| 张家口市| 和硕县| 陇川县| 密山市| 永康市|