C++ 賦值與交換法則

在C++中,賦值與交換法則(Assignment and Swap Idiom)通常指的是在實現類的賦值操作符(operator=)時,結合拷貝構造交換操作來確保強異常安全保證(Strong Exception Safety Guarantee)的一種設計模式。這種模式也被稱為Copy-and-Swap Idiom。它是一種優雅且高效的方式,用于實現賦值操作符,同時避免資源泄漏和異常不安全的情況。

核心概念

Copy-and-Swap Idiom 的核心是通過拷貝構造創建一個臨時對象,然后通過交換操作將臨時對象的內容與當前對象的內容交換,從而完成賦值操作。這種方法利用了C++的資源管理機制(RAII)和異常安全特性。

實現步驟

以下是 Copy-and-Swap Idiom 的典型實現步驟:

  1. 定義拷貝構造函數:創建一個新的對象,深拷貝傳入對象的數據。
  2. 定義交換函數(swap):通常是一個成員函數或友元函數,用于無異常地交換兩個對象的內容(通常使用 std::swap 或自定義交換邏輯)。
  3. 定義賦值操作符:通過拷貝構造和交換實現賦值。

代碼示例

以下是一個完整的實現示例:

#include <algorithm> // for std::swap
#include <cstddef>   // for size_tclass MyString {
private:char* data_;size_t length_;public:// 構造函數MyString(const char* str = "") : data_(nullptr), length_(0) {length_ = std::strlen(str);data_ = new char[length_ + 1];std::strcpy(data_, str);}// 拷貝構造函數MyString(const MyString& other) : data_(nullptr), length_(0) {length_ = other.length_;data_ = new char[length_ + 1];std::strcpy(data_, other.data_);}// 析構函數~MyString() {delete[] data_;}// 交換函數(無異常拋出)friend void swap(MyString& lhs, MyString& rhs) noexcept {std::swap(lhs.data_, rhs.data_);std::swap(lhs.length_, rhs.length_);}// 賦值操作符(Copy-and-Swap Idiom)MyString& operator=(MyString other) {swap(*this, other);return *this;}// 其他方法(例如打印內容)void print() const {std::cout << data_ << std::endl;}
};// 測試代碼
int main() {MyString a("Hello");MyString b("World");a.print(); // 輸出: Hellob.print(); // 輸出: Worlda = b;     // 賦值操作a.print(); // 輸出: Worldreturn 0;
}

工作原理

  1. 拷貝構造:在賦值操作 a = b 中,參數 MyString other 是按值傳遞的,這會調用拷貝構造函數創建一個臨時對象 other,該對象是 b 的深拷貝。
  2. 交換swap(*this, other) 將當前對象(*this)的內容與臨時對象 other 的內容交換。由于 swap 是無異常拋出的(noexcept),這一步是安全的。
  3. 銷毀臨時對象:臨時對象 other 在離開作用域時自動銷毀,其析構函數會清理原來 *this 的資源(因為它們已被交換到 other 中)。

優點

  1. 強異常安全保證:如果拷貝構造函數拋出異常,*this 的狀態不會被修改,因為交換操作本身是無異常的。
  2. 代碼簡潔:將拷貝和賦值邏輯統一到拷貝構造函數和 swap 函數中,減少代碼重復。
  3. 資源管理安全:通過 RAII(資源獲取即初始化),確保資源(如動態分配的內存)在異常情況下也能正確釋放。

注意事項

  1. 性能考慮:Copy-and-Swap 需要一次拷貝構造和一次交換,相比直接賦值可能有輕微性能開銷。但在現代 C++ 中,編譯器優化(如 NRVO)通常能減少不必要的拷貝。
  2. 適用場景:這種模式適用于管理動態資源(如內存、文件句柄等)的類。如果類沒有動態資源,可能不需要如此復雜的實現。
  3. 移動語義:在 C++11 及以上版本中,可以結合移動構造函數和移動賦值操作符進一步優化性能,但 Copy-and-Swap 仍然是一個可靠的通用解決方案。

擴展:結合移動語義

在 C++11 及以上,賦值操作符可以接受右值引用以支持移動語義,通常仍可通過 Copy-and-Swap Idiom 實現:

MyString& operator=(MyString other) noexcept {swap(*this, other);return *this;
}

這里的 other 可以是左值(觸發拷貝)或右值(觸發移動),編譯器會自動選擇合適的構造函數。

總結

C++ 的賦值與交換法則(Copy-and-Swap Idiom)通過拷貝構造和交換操作實現賦值操作符,提供強異常安全保證和簡潔的代碼結構。它是 C++ 中處理資源管理的標準模式之一,廣泛應用于需要深拷貝的類設計中。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91151.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91151.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91151.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ambari中文漢化

Ambari-ZH 當前Ambari的漢化版本為2.7.4,漢化采用對該版本的ambari源碼直接修改的方式進行,如有翻譯不當之處,請批評指正 一、使用方法如下&#xff1a; 方式一&#xff1a;直接下載 下載地址&#xff1a;https://github.com/ukayunnuo/Ambari-2.7.x-zh/releases/download/…

表格之固定列和表頭

說明 利用粘性定位實現 列固定 td.fixed {position: sticky;left: 0;z-index: 5;/* 最好指定背景&#xff0c;否則滑動時會顯示下面的列 */background-color: #f8f9fa; }表頭固定 <head><style>.table-container {position: relative;display: flex;overflow: hidd…

React 圖標庫發布到 npm 倉庫

將搭建的 React 圖標庫發布到 npm 倉庫需要經過一系列步驟&#xff0c;包括配置 package.json、構建代碼、注冊 npm 賬號、測試和發布。以下是詳細流程&#xff1a; 1. 準備工作 (1) 確保項目結構完整 圖標庫的典型結構&#xff08;以 Rollup 構建為例&#xff09;&#xff1…

Java學習第八十四部分——HttpClient

目錄 一、前言介紹 二、主要特點 三、功能用法 四、應用場景 五、最佳實踐 六、總結歸納 一、前言介紹 HttpClient 是一個用于發送 HTTP 請求和接收 HTTP 響應的客戶端庫&#xff0c;廣泛應用于 Web 開發、API 調用、微服務通信等場景。 二、主要特點 支持多種HTTP方…

學習筆記-中華心法問答系統的性能提升

1.簡介本周主要任務是自行查找文獻&#xff0c;針對源代碼進行性能提升&#xff0c;主要包括三個方面&#xff1a;預處理&#xff1a;分詞、關鍵詞提取、詞向量生成&#xff1b;文本分析&#xff1a;從多個關鍵詞的詞向量&#xff0c;如何到一句話的語義理解&#xff1b;問題分…

Python爬蟲03_Requests破解百度翻譯

爬取百度翻譯頁面信息 以POST方法發送JSON數據&#xff0c;爬取響應信息&#xff0c;并且需要對響應信息對象類型進行區分。 import requests import json#1.指定url post_url https://fanyi.baidu.com/sug#2.進行UA封裝 headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; …

【C++進階】第8課—紅黑樹封裝map和set

文章目錄1. map和set的源碼及框架分析2. 模擬實現map和set2.1 實現可以復用紅黑樹的框架&#xff0c;支持insert操作2.2 實現迭代器iterator2.2.1 實現迭代器2.2.2 實現迭代器 - -2.2.3 解決key不能修改的問題2.2.4 重載operator[ ]3. 完整代碼3.1 紅黑樹頭文件RBTree.h3.2 mym…

【機器學習深度學習】DeepSpeed框架:高效分布式訓練的開源利器

目錄 前言 一、DeepSpeed 簡介 1.1 定位與目標 1.2 集成生態 二、核心技術解析 2.1 ZeRO&#xff08;Zero Redundancy Optimizer&#xff09; 2.2 顯存優化技術 2.3 推理優化與通信機制 三、DeepSpeed 的優勢與特性總結 四、 典型應用場景 &#x1f9e0; 大模型訓練…

從視覺到現實:掌握計算機視覺技術學習路線的十大步驟

成長路上不孤單&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;【14后&#x1f60a;///計算機愛好者&#x1f60a;///持續分享所學&#x1f60a;///如有需要歡迎收藏轉發///&#x1f60a;】今日分享關于計算機視覺技術學習路線方面的相關內容…

DeepSeek MoE 技術解析:模型架構、通信優化與負載均衡

1. MoE 簡介 MoE&#xff08;Mixed Expert Models&#xff09;&#xff0c;混合專家模型。在 Transformer 的 FFN 中&#xff0c;有一個重要的觀察是&#xff0c;其計算過程中的神經元激活是非常稀疏的&#xff0c;在一次計算中只有 90%的輸入激活不到 5%的神經元&#xff0c;…

【Linux】pthread學習筆記

1. 線程基礎(1) 線程創建與終止#include <pthread.h> // 創建線程 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg); // 終止當前線程 void pthread_exit(void *retval); // 等待線程結束 int pthread_joi…

p5.js 從零開始創建 3D 模型,createModel入門指南

點贊 關注 收藏 學會了 如果你已經開始探索 p5.js 的 3D 世界&#xff0c;那么createModel()這個 API 絕對是你需要掌握的強大工具。它允許你創建自定義的 3D 幾何模型&#xff0c;為你的創意提供無限可能。 什么是 createModel ()&#xff1f; createModel() 用于從一個…

react 的 useTransition 、useDeferredValue

useTransition 用于 管理狀態更新的過渡&#xff08;pending&#xff09;狀態&#xff0c;避免因高優先級任務&#xff08;如用戶輸入&#xff09;被低優先級任務&#xff08;如數據獲取或復雜計算&#xff09;阻塞而導致的界面卡頓。 它特別適用于&#xff0c;需要 區分緊急更…

Unity的GameObject.Instantiate的使用

在Unity游戲引擎中&#xff0c;GameObject.Instantiate 是一個核心方法&#xff0c;用于在運行時動態創建游戲對象的副本。它常用于實例化預制體&#xff08;Prefab&#xff09;&#xff0c;例如生成敵人、子彈或場景元素。以下是其使用方法的詳細說明&#xff0c;包括語法、參…

【CSS】盒子類型

CSS盒子模型是網頁布局的核心基礎&#xff0c;每個HTML元素都被視為一個矩形盒子&#xff0c;由??內容&#xff08;Content&#xff09;、內邊距&#xff08;Padding&#xff09;、邊框&#xff08;Border&#xff09;、外邊距&#xff08;Margin&#xff09;??四部分組成。…

《嵌入式C語言筆記(十五):字符串操作與多維指針深度解析》

1.字符串與指針安全操作核心函數與陷阱函數功能安全替代功能strcpy字符串拷貝strncpy復制前n個&#xff0c;最多strlen個&#xff0c;超出有效長度&#xff0c;按原樣復制strcat字符串拼接strncatdest只連接src的前n個&#xff0c;如果n超過有效長度&#xff0c;按原樣鏈接strc…

每日學習筆記記錄(分享更新版-凌亂)

函數和變量都需要滿足&#xff1a;先聲明后使用&#xff08;重要&#xff09;在 函數的聲明中&#xff0c;形參的名字可以省略函數的定義是一種特殊的是聲明&#xff0c;比聲明更加強大&#xff1b;函數使用前必須進行聲明&#xff0c;但不必要聲明具體定義.h——函數的聲明.c—…

Windows提權(MS09-012 巴西烤肉)

演示環境&#xff1a;windows-2003前提&#xff1a;提權的前提條件是拿到服務器的webshell演示以iis的中間件解析漏洞為例&#xff08;test.asp;.jpg&#xff09; Windows提權拿到webshell之后&#xff0c;使用菜刀&#xff0c;蟻劍&#xff0c;冰蝎或者哥斯拉連接上服務器&…

常見依賴于TCP/IP的應用層協議

Protocol 協議 Acronym 縮寫 Port 端口 Description 描述 Telnet Telnet 23 Remote login service 遠程登錄服務 Secure Shell SSH 22 Secure remote login service 安全遠程登錄服務 Simple Network Management Protocol 簡單網絡管理協議 SNMP 161-162 Manage network d…

XML Schema 指示器:全面解析與深度應用

XML Schema 指示器:全面解析與深度應用 引言 XML Schema 是一種用于定義 XML 文檔結構的語言,它為 XML 文檔提供了嚴格的框架,以確保數據的準確性和一致性。在本文中,我們將深入探討 XML Schema 的基本概念、關鍵特性、指示器的作用以及其實際應用。 XML Schema 的基本概…