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

C++ 類別物件複製建構函式深度解析:淺層複製與深層複製

     編輯:關於C++

一、複製建構函式基本語法

ClassName(const ClassName& other); // 唯一參數為 const 參考
  • 在以同類別物件初始化新物件時自動呼叫:ClassName b = a;、func(a)(值傳遞)、return a(值傳回)。
  • 若未自行定義,編譯器產生預設複製建構函式:執行位元級逐一複製(淺層複製)。
  • 自行定義可阻止編譯器產生預設版本,掌控複製語意。

二、淺層複製問題

若類別含指標成員指向動態記憶體,預設複製僅複製指標值,導致兩物件共用同一記憶體區塊:

class Bad {
    int* data;
public:
    Bad(int n) { data = new int[n]; }
    ~Bad() { delete[] data; } // 雙重釋放崩潰!
};
int main() {
    Bad a(10);
    Bad b = a; // 淺層複製:a.data == b.data
} // a、b 解構時雙重 delete 同一記憶體

三、深層複製實作

在複製建構函式中重新配置記憶體並複製內容:

class Good {
    int* data;
    size_t len;
public:
    Good(int n) : len(n) { data = new int[n]; }
    Good(const Good& other) : len(other.len) { // 深層複製
        data = new int[len];
        std::copy(other.data, other.data + len, data);
    }
    Good& operator=(const Good& other) { // 指派運算子同理
        if (this != &other) {
            delete[] data;
            len = other.len;
            data = new int[len];
            std::copy(other.data, other.data + len, data);
        }
        return *this;
    }
    ~Good() { delete[] data; }
};

四、完整範例:字串類別

#include 
#include 
using namespace std;

class CA {
    int a;
    char* str;
public:
    CA(int b, const char* cstr) : a(b) {
        str = new char[b];
        strcpy(str, cstr);
    }
    CA(const CA& c) : a(c.a) { // 深層複製
        str = new char[a];
        if (str) strcpy(str, c.str);
    }
    void Show() { cout << str << endl; }
    ~CA() { delete[] str; }
};

int main() {
    CA A(10, "Hello!");
    CA B = A; // 呼叫複製建構函式
    B.Show(); // 輸出 Hello!
    return 0;
}

五、現代 C++ 最佳實務(C++11 起)

  1. 三/五法則:若需自訂解構函式、複製建構、複製指派,通常也需移動建構、移動指派。
  2. Rule of Zero:優先使用 std::string、std::vector、std::unique_ptr、std::shared_ptr 等 RAII 類別,讓編譯器自動合成正確的特殊成員函式,完全避免手動管理記憶體。
  3. 禁用複製:唯一擁有權語意類別用 = delete 禁用複製:
    CA(const CA&) = delete; CA& operator=(const CA&) = delete;

六、總結對照表

場景預設行為需自訂時
無指標/資源成員正確(位元複製即語意複製)罕見
含指標/動態資源淺層複製 → 雙重釋放/資料競爭必須實作深層複製或禁用
含參考/const 成員編譯錯誤(預設複製無法處理)必須自訂
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved