自定義類的賦值運算符重載函數功能類似內置賦值運算符,但與拷貝構造函數、析構函數一樣,必須嚴謹處理「深拷貝」與「淺拷貝」問題。若未顯式定義,編譯器會自動生成一個預設的賦值運算符重載函數,但這通常只能實現淺拷貝,對於包含指針成員的類極其危險。
賦值運算符重載函數的定義語法與其他運算符重載類似,通常返回類的引用(ClassName&)以支援鏈式賦值。核心邏輯在於:
delete[])。*this。#include <iostream>
#include <cstring>
using namespace std;
class Internet {
public:
// 構造函數:動態分配字符串內存
Internet(char *name, char *url) {
this->name = new char[strlen(name) + 1];
this->url = new char[strlen(url) + 1];
if (name) strcpy(this->name, name);
if (url) strcpy(this->url, url);
}
// 拷貝構造函數:深拷貝
Internet(Internet &temp) {
this->name = new char[strlen(temp.name) + 1];
this->url = new char[strlen(temp.url) + 1];
if (name) strcpy(this->name, temp.name);
if (url) strcpy(this->url, temp.url);
}
// 析構函數:釋放資源
~Internet() {
delete[] name;
delete[] url;
}
// 賦值運算符重載:核心深拷貝邏輯
Internet& operator=(Internet &temp) {
// 1. 自賦值檢查(最佳實踐)
if (this == &temp) return *this;
// 2. 釋放原有資源
delete[] this->name;
delete[] this->url;
// 3. 重新分配並深拷貝
this->name = new char[strlen(temp.name) + 1];
this->url = new char[strlen(temp.url) + 1];
if (this->name) strcpy(this->name, temp.name);
if (this->url) strcpy(this->url, temp.url);
return *this;
}
public:
char *name;
char *url;
};
int main() {
Internet a("中國軟件開發實驗室", "www.cndev-lab.com");
Internet b = a; // 調用拷貝構造函數(對象不存在時)
cout << b.name << endl << b.url << endl;
Internet c("美國在線", "www.aol.com");
b = c; // 調用賦值運算符重載(對象已存在時)
cout << b.name << endl << b.url << endl;
system("pause");
return 0;
}
Internet b = a;),對象尚未存在,直接構造。b = c;),需先清理原有資源再複製新數據。在賦值運算符中,delete[] 釋放指針指向的堆內存是解決深拷貝問題的關鍵。因為目標對象 b 已經構造過,其 name 和 url 指針已指向確定的堆區域,若不先釋放再分配,會導致記憶體洩漏或區域大小不匹配。
if (this == &rhs) return *this;)。std::string 替代 char*,利用標準庫自動管理記憶體,避免手動深拷貝的錯誤風險。