首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 拷貝構造函數與賦值運算符重載:核心區別、臨時對象陷阱與最佳實踐

     編輯:C++ 入門

C++ 拷貝構造函數與賦值運算符重載:核心區別、臨時對象陷阱與最佳實踐

這是 C++ 面試必考、工程必懂的核心知識點。本文通過 String 類實戰演示兩者區別,並深入分析臨時對象生命週期陷阱。

根本區別速查表

特性拷貝構造函數賦值運算符
調用時機用現有對象初始化新對象將現有對象賦值給已存在對象
是否創建新對象是否
需檢查自賦值否(新對象不可能等於源)是(if (this == &rhs) return *this;)
需釋放舊資源否(新對象無舊資源)是(先 delete 再 new)
返回類型無(構造函數無返回)Type&(支持鏈式賦值)

String 類完整實現對比

class String {
public:
    String(const char* str = nullptr);        // 普通構造
    String(const String& other);              // 拷貝構造
    ~String();                                // 析構
    String& operator=(const String& other);   // 賦值運算符
private:
    char* m_data;
};

// 拷貝構造:直接構建新對象
String::String(const String& other) {
    int len = strlen(other.m_data);
    m_data = new char[len + 1];
    strcpy(m_data, other.m_data);
}

// 賦值運算符:處理自賦值、釋放舊內存、深拷貝
String& String::operator=(const String& other) {
    if (this == &other) return *this;  // 自賦值檢查
    delete[] m_data;                   // 釋放舊資源
    int len = strlen(other.m_data);
    m_data = new char[len + 1];
    strcpy(m_data, other.m_data);
    return *this;
}

微妙調用差別演示

void test() {
    B b1;
    B b2 = b1;   // 拷貝構造(初始化)
    B b3;
    b3 = b1;     // 賦值運算符(已存在對象)
}

輸出:

default constructor
copyed by parameter 0   ← b2 拷貝構造
default constructor
= by parameter 0        ← b3 賦值運算符

臨時對象生命週期陷阱(核心考點)

B play(B b) { return b; }  // 參數按值傳遞,返回按值

void test() {
    play(1);          // ①
    B t1 = play(2);   // ②
    B t2;
    t2 = play(3);     // ③
}

關鍵規則:

  1. 參數傳遞調用拷貝構造(play(1) 中 1 隱式轉換構造 B,再拷貝構造參數 b)
  2. 返回值:若無接收對象(①),創建臨時對象保存返回值,被調用函數結束時析構
  3. 返回值:若有接收對象(② 初始化用拷貝構造,③ 賦值用賦值運算符),返回值賦值給接收對象,調用函數結束時析構

完整輸出流程分析見原文,核心在於區分「被調用者結束」vs「調用者結束」銷毀臨時對象的時機差異。

現代 C++ 最佳實踐

  • Rule of Five:自定義析構/拷貝構造/拷貝賦值/移動構造/移動賦值
  • 優先使用 std::string, std::vector 等標準容器,避免手動管理裸指針
  • 若類管理資源,考慮 移動語義(C++11)避免不必要的深拷貝
  • 將拷貝操作標記為 delete 禁止拷貝(如單例、非拷貝類),或 default 交由編譯器生成
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved