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

C++ 複製建構函數與重載賦值運算子完整總結:調用時機、深淺拷貝與細節陷阱

     編輯:關於C語言

複製建構函數與重載賦值運算子是 C++ 物件語意的核心。本文系統總結其定義、調用時機、實作要點(深/淺拷貝)、細節規則與常見陷阱,並附完整程式碼驗證。

定義原型

class CTest {
public:
    CTest();                          // 預設建構
    ~CTest();                         // 解構
    CTest(const CTest &);             // 複製建構
    CTest& operator=(const CTest &);  // 重載賦值
};
  • 未顯式宣告時,編譯器自動產生隱式版本(逐成員淺拷貝)。
  • 顯式宣告後,編譯器不再產生隱式版本。

調用時機實測驗證

class CTest {
public:
    CTest() {}
    ~CTest() {}
    CTest(const CTest &) { cout << "copy constructor." << endl; }
    void operator=(const CTest &) { cout << "operator=" << endl; }
    void Test(CTest test) {}           // 傳值參數
    CTest Test2() { CTest a; return a; } // 傳值回傳
    void Test3(CTest &test) {}         // 參考參數
    CTest &Test4() { return *new CTest; } // 參考回傳
};

int main() {
    CTest obj, obj1(obj);          // 1. 宣告時初始化 → 複製建構
    obj1 = obj;                    // 2. 已存在物件賦值 → 重載賦值
    obj.Test(obj1);                // 3. 傳值參數 → 複製建構(建立臨時物件)
    CTest obj2 = obj.Test2();      // 4. 傳值回傳 → 複製建構(臨時物件) + 重載賦值
    obj2.Test3(obj);               // 5. 參考參數 → 無複製
    CTest obj3 = obj.Test4();      // 6. 參考回傳 → 無複製(直接綁定)
}

核心判斷原則

宣告同時初始化 → 複製建構函數
已存在物件賦值 → 重載賦值運算子

深拷貝實作要點(含動態記憶體成員)

class CTest {
    wchar_t *pValue;
    static const int MAXSIZE = 260;
public:
    CTest(wchar_t *init) {
        pValue = new wchar_t[MAXSIZE];
        wcscpy_s(pValue, MAXSIZE, init);
    }
    ~CTest() { delete[] pValue; pValue = nullptr; }

    // 複製建構:配置新記憶體 + 逐字元複製
    CTest(const CTest &t) {
        pValue = new wchar_t[MAXSIZE];
        wcscpy_s(pValue, MAXSIZE, t.pValue);
    }

    // 重載賦值:自賦值檢查 + 釋放舊記憶體 + 配置新 + 複製
    CTest& operator=(const CTest &t) {
        if (this == &t) return *this;  // 自賦值防護
        delete[] pValue;               // 釋放舊資源
        pValue = new wchar_t[MAXSIZE];
        wcscpy_s(pValue, MAXSIZE, t.pValue);
        return *this;
    }
};

複製建構函數細節規則

  1. 參數型別:第一參數為 X&、const X&、volatile X&、const volatile X& 之一,且無其他參數或皆有預設值,即為複製建構函數。
  2. 多重複製建構:類別可同時擁有 X(const X&) 與 X(X&);若僅有非 const 版,則無法以 const 物件初始化。
  3. 編譯器預設:未宣告時編譯器產生 X(const X&) 或 X(X&),視上下文而定。

現代 C++ 建議

  • 遵循 Rule of Five:若需自訂解構/複製建構/賦值,通常也需宣告移動建構/移動賦值(C++11)。
  • 優先使用 std::unique_ptr、std::string、std::vector 等 RAII 類別,避免手動管理動態記憶體。
  • 若類別無資源管理需求,預設複製/移動語意通常正確,無需額外程式碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved