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

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

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

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

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

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

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

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

移動(dòng)語(yǔ)義的核心思想是:既然右值(臨時(shí)對(duì)象)馬上就要銷毀了,我們沒(méi)必要復(fù)制它的資源,直接“偷”過(guò)來(lái)用就行了。

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

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

作用

將源對(duì)象(other)的資源指針直接轉(zhuǎn)移給新對(duì)象,并將源對(duì)象的指針置為 nullptr(或其他安全狀態(tài)),防止析構(gòu)時(shí)重復(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";
    }
    // --- 移動(dòng)構(gòu)造函數(shù) ---
    MyVector(MyVector&& other) noexcept 
        : data(other.data), size(other.size) {
        // 關(guān)鍵步驟:竊取指針
        other.data = nullptr; // 將源對(duì)象置為空,防止其析構(gòu)時(shí)釋放這塊內(nèi)存
        other.size = 0;
        std::cout << "移動(dòng)構(gòu)造: 轉(zhuǎn)移所有權(quán)\n";
    }
    // 析構(gòu)函數(shù)
    ~MyVector() {
        if (data) {
            delete[] data;
            std::cout << "析構(gòu): 釋放內(nèi)存\n";
        }
    }
};
// 使用場(chǎng)景
MyVector createVector() {
    MyVector temp(100);
    return temp; // 返回臨時(shí)對(duì)象(右值)
}
int main() {
    // 這里會(huì)觸發(fā)移動(dòng)構(gòu)造函數(shù),而不是拷貝構(gòu)造
    MyVector v = createVector(); 
    return 0;
}

3. 移動(dòng)賦值運(yùn)算符 (Move Assignment Operator)

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

作用

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

代碼示例

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

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

A.noexcept的重要性

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

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

B.std::move是什么?

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

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

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

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

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

如果你只定義了移動(dòng)操作而沒(méi)有定義拷貝操作,編譯器會(huì)自動(dòng)刪除默認(rèn)的拷貝構(gòu)造和拷貝賦值函數(shù)(因?yàn)橘Y源已經(jīng)被移走了,默認(rèn)拷貝是不安全的)。

D. 成員變量的自動(dòng)移動(dòng)

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

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

總結(jié)對(duì)比

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

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

相關(guān)文章

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

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

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

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

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

    C++發(fā)郵件簡(jiǎn)單實(shí)例詳解

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

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

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

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

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

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

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

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

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

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

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

    C語(yǔ)言近萬(wàn)字為你講透樹(shù)與二叉樹(shù)

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

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

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

最新評(píng)論

汝城县| 江永县| 扶沟县| 奉化市| 云和县| 长宁区| 若羌县| 广丰县| 嘉义县| 新化县| 荃湾区| 福安市| 鹿邑县| 三原县| 聂拉木县| 石渠县| 鄂温| 富锦市| 遂昌县| 武平县| 平度市| 新兴县| 上思县| 苍山县| 惠东县| 福建省| 宜兴市| 蛟河市| 大竹县| 资源县| 霞浦县| 汝阳县| 墨脱县| 旌德县| 新河县| 咸宁市| 屯门区| 长兴县| 阜宁县| 枝江市| 扎鲁特旗|