若類管理**資源**(堆內存、文件句柄、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 | 編譯錯誤 (被刪除的拷貝函數) |
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_; }
};
class NonCopyable {
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
// 或繼承 boost::noncopyable / 私有聲明不定義 (C++03)
};
class SharedResource {
std::shared_ptr res_; // 自動引用計數,無需手寫三大函數
};
vector, string, unique_ptr, shared_ptr),編譯器自動合成正確的拷貝/移動操作 (Rule of Zero)類中是否包含:new/malloc、裸指針、FILE*、系統句柄、unique_ptr、thread、mutex、非拷貝類對象?
→ 是 → 必須顯式處理拷貝控制
→ 否 → 編譯器合成版本通常正確 (Rule of Zero)