重載operator=時,為什麼要在開頭檢查if (this == &rhs) return *this;?這不是多此一舉嗎?
MyClass obj;
obj = obj; // 顯式自賦值
obj = std::move(obj); // 移動自賦值 (C++11)
container[i] = container[j]; // 容器元素複製時 i==j
*ptr1 = *ptr2; // 指針指向同一對象
典型資源管理類實現:
MyClass& operator=(const MyClass& rhs) {
delete[] data_; // 1. 釋放舊資源
data_ = new char[len_]; // 2. 分配新內存
std::copy(rhs.data_, rhs.data_ + len_, data_); // 3. 複製數據
return *this;
}
若this == &rhs:
delete[] data_釋放了rhs.data_指向的內存(因為是同一塊)new char[len_]可能分配到不同地址std::copy從已釋放的內存讀取 → 未定義行為(崩潰、數據損壞、靜默錯誤)// 模式一:指針比較(最常用)
MyClass& operator=(const MyClass& rhs) {
if (this == &rhs) return *this; // 自賦值保護
// ... 正常複製邏輯
return *this;
}
// 模式二:Copy-and-Swap 惯用法(強異常安全、天然防自賦值)
MyClass& operator=(MyClass rhs) { // 參數按值傳遞觸發拷貝構造
swap(*this, rhs); // 交換資源
return *this; // rhs 析構時釋放舊資源
}
swapMyClass& operator=(MyClass&& rhs) noexcept {
if (this == &rhs) return *this; // 移動自賦值同樣需檢查
delete[] data_;
data_ = rhs.data_;
len_ = rhs.len_;
rhs.data_ = nullptr;
rhs.len_ = 0;
return *this;
}
if (this == &rhs) return *this;std::unique_ptr、std::vector自動處理資源管理,編譯器生成的特殊成員函數通常足夠自賦值檢查不是「多此一舉」,而是資源管理類的生存底線。Copy-and-Swap惯用法以優雅方式解決此問題並提供強異常安全。現代C++應盡量避免手寫資源管理,讓標準庫組件承擔複雜度。