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

C++ 類別物件深拷貝與淺拷貝建構函數完整圖解

     編輯:VC 教學

預設拷貝建構函數:淺拷貝

當類別未自訂拷貝建構函數時,編譯器自動產生「逐成員拷貝」版本:


class Test {
public:
    Test(int v) : p1(v) {}
    int p1;
};

Test a(99);
Test b = a; // 呼叫編譯器產生的淺拷貝建構函數

對於 int 等值型別成員,淺拷貝無問題。但若成員為**指標/資源控制代碼**,淺拷貝會導致雙重釋放、記憶體洩漏、資料競爭。

深拷貝:自訂拷貝建構函數


class DeepCopy {
    char* buffer;
    size_t len;
public:
    DeepCopy(const char* s) : len(strlen(s)) {
        buffer = new char[len + 1];
        strcpy(buffer, s);
    }
    // 自訂拷貝建構函數:分配新記憶體並複製內容
    DeepCopy(const DeepCopy& other) : len(other.len) {
        buffer = new char[len + 1];
        strcpy(buffer, other.buffer);
    }
    ~DeepCopy() { delete[] buffer; }
    // 拷貝指派運算子同理需自訂 (Rule of Three)
    DeepCopy& operator=(const DeepCopy& other) {
        if (this != &other) {
            delete[] buffer;
            len = other.len;
            buffer = new char[len + 1];
            strcpy(buffer, other.buffer);
        }
        return *this;
    }
};

C++11 移動語意:Rule of Five

新增移動建構函數與移動指派運算子,避免不必要的深拷貝:


DeepCopy(DeepCopy&& other) noexcept : buffer(other.buffer), len(other.len) {
    other.buffer = nullptr;
    other.len = 0;
}
DeepCopy& operator=(DeepCopy&& other) noexcept {
    if (this != &other) {
        delete[] buffer;
        buffer = other.buffer;
        len = other.len;
        other.buffer = nullptr;
        other.len = 0;
    }
    return *this;
}

最佳實踐總結

場景策略
無動態資源成員 (純值型別)使用預設拷貝/指派 (Rule of Zero)
擁有獨佔資源 (指標、檔案控制代碼、socket)自訂深拷貝 + 移動語意 (Rule of Five),或使用 std::unique_ptr/std::string/std::vector 讓編譯器自動正確生成 (Rule of Zero)
共享資源 (參考計數)使用 std::shared_ptr,預設拷貝即正確

核心口訣

「誰分配,誰釋放;拷貝即複製資源,移動即轉移所有權。善用標準庫容器與智慧型指標,讓編譯器幫你守規矩。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved