首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 拷貝控制操作何時必須自定義?三大函數法則詳解

     編輯:程式設計綜合問答

簡單判斷規則

若類管理**資源**(堆內存、文件句柄、Socket、鎖、GPU 顯存等),**必須**顯式聲明/定義三大函數:

  • 複製構造函數 T(const T&)
  • 複製賦值運算符 T& operator=(const T&)
  • 析構函數 ~T()

C++11 後擴展為「五大函數」,增加移動構造與移動賦值。

何謂「管理資源」?

資源類型典型成員淺拷貝後果
動態內存raw pointer, new[]雙重釋放、內存洩漏
文件/網絡句柄FILE*, SOCKET重複關閉、句柄泄漏
系統對象HANDLE, pthread_mutex_t競態、未定義行為
非拷貝類成員std::unique_ptr, std::thread編譯錯誤 (被刪除的拷貝函數)

三種處理策略

1. 深拷貝 (值語義)

class Buffer {
    char* data_;
    size_t size_;
public:
    Buffer(const Buffer& other) : size_(other.size_) {
        data_ = new char[size_];
        memcpy(data_, other.data_, size_);
    }
    Buffer& operator=(const Buffer& other) {
        if (this != &other) {
            delete[] data_;
            size_ = other.size_;
            data_ = new char[size_];
            memcpy(data_, other.data_, size_);
        }
        return *this;
    }
    ~Buffer() { delete[] data_; }
};

2. 禁用拷貝 (唯一所有權)

class NonCopyable {
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
    // 或繼承 boost::noncopyable / 私有聲明不定義 (C++03)
};

3. 共享所有權 (智能指針)

class SharedResource {
    std::shared_ptr res_; // 自動引用計數,無需手寫三大函數
};

現代 C++ 最佳實踐

  1. 優先使用 RAII 容器/智能指針 (vector, string, unique_ptr, shared_ptr),編譯器自動合成正確的拷貝/移動操作 (Rule of Zero)
  2. 必須手寫時,採用 Copy-and-Swap 惯用法 保證異常安全
  3. C++11 起顯式聲明 = default / = delete 表達意圖

快速自查清單

類中是否包含:new/malloc、裸指針、FILE*、系統句柄、unique_ptr、thread、mutex、非拷貝類對象?
→ 是 → 必須顯式處理拷貝控制
→ 否 → 編譯器合成版本通常正確 (Rule of Zero)

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