Re: [問題] overload operator=

看板C_and_CPP作者 (最愛朴素妍)時間15年前 (2010/10/08 05:51), 編輯推噓0(005)
留言5則, 2人參與, 最新討論串2/3 (看更多)
※ 引述《tropical72 (藍影)》之銘言: : 遇到的問題: (題意請描述清楚) : class A{ : public: : int *array; : size_t Len; : A(size_t len=200); : ~A(); : A &operator=(const A& Obj); : A &operator=(const char* Str); : A &operator++(); : A operator+(const A& Obj); : Complex operator+(const Complex&); : }; 看來這是動態陣列之類的東西 : A::A(size_t len) { : Len = len; : array = new int[Len]; : } : A::~A(){ : delete [] array; : array = NULL; : } : A A::operator+(const A& Obj){ : A tmp; : .... : return tmp; : } 其實 operator + 可以用 += 來實作, 不過不是這次的重點 : char String[] = "1234"; : A obj1, obj2; : obj1 = obj2; // (a) : obj1 = "1234"; // (b) : (1) 若只覆載類別 A 時,是否有必要 overload = ?? (只考慮 case (a) ) ^你想問的應該是 : 這種情況下, 是否有必要重載一個 左邊運算子為 A 類別物件的 operator =. 先說明左右運算子皆為 A物件的版本, 考慮以下的程式碼 : 1: { 2: A obj1; 3: { 4: A obj2; 5: obj2 = obj1; 6: }// obj2 被解構 7: }// obj1 被解構 因為你在建構子中都有做 new 的動作來配置記憶體給成員 array, 所以到第 4行為止都是安全的, 不過在執行第 5行 程式碼的時候, 使用了內建的copy assignment, 預設的動 作就跟你使用 : memcpy( &obj2, &obj1, sizeof(A) ); 是一樣的, obj2 內所有的資料將會跟 obj1 一樣, 所以意 味著本來 obj2 在建構子裡 new 的那塊記憶體已經參考不 到了! 造成記憶體洩漏. 又因為此時 obj2 跟 obj1的資料 成員是指到同一塊記憶體, 在第 6行 obj2被解構之後, 第 7行 obj1如果再被解構, 你就對了同一塊記憶體 delete 兩次. 而右邊運算子為字串的版本, 不實作是沒辦法呼叫的,所以 比較沒有問題. : (2) 若上述為否,若同時覆載類別 A 與 字串 時, ( 考慮 case (a),(b) ) : 是否二個 overload 都要寫?還是只要寫字串的就行了? 一般來說, 兩個 copy assignment 都要提供, 因為使用者 一旦可以寫 obj = "123" 這樣的程式碼, 通常也會想試試 obj = obj2, 為了避免使用者誤用導致系統崩潰, 要不將 operator =( A const& )這運算子宣告的存取權限設定為 private 且不提供實作, 就是用具名的成員函式如 : obj.receiveString( "123" ); 直接說明此操作存在的目的, 是比較好的方法.不過一旦你 實作了operator=, 通常也需要連帶實作對應的拷貝建構子 , 其中一個原因就是沒辦法呼叫使用者會不爽(因為從語意 上來看兩者是相等的,可以賦值卻不能丟到建構子裡是很奇 怪的事情). : (3) 當然 overload operator+ 時,由於我建構子有寫了 new : 此時之 tmp 為區域變數,當執行完該函數後, : 記憶體應全都清掉了,所以這種重載是失敗的嗎? 預設的 copy constructor的行為跟copy assignment是一樣 的, 不管最佳化的情況, 用來回傳的物件姑且稱它為 ret, 回傳之前會呼叫其拷貝建構子來建構物件, 就像這樣 : A ret(tmp); 問題又回到(1)說的那樣, 對同一塊記憶體 delete了兩次, 只差沒有記憶體洩漏而已, 這也是必須實作拷貝建構子的原 因之一. : 謝謝指教 感激不盡 -- ◢████ ◢█ ◢██◣ ◢█ ◢███ ◢█ T-ara版怎麼去 ████◢█████s ~> T-ara ███ █ ◢█歡迎您的光臨 ███████████恩靜智妍孝敏 ███ ██ 素妍居麗寶藍 ████◥██◤ █████ψmakigoto123 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115 ※ 編輯: loveme00835 來自: 140.121.197.115 (10/08 06:15)

10/08 06:25, , 1F
非常感謝您的回覆, 晚上K過之後再請教您.非常感激
10/08 06:25, 1F

10/08 19:26, , 2F
若我在~A()中判斷 if(Array!=NULL) delete [] Array;
10/08 19:26, 2F

10/08 19:27, , 3F
是否能解決上述問題呢?
10/08 19:27, 3F

10/08 19:30, , 4F
任何一個物件在解構的時候, 設成null的是自己的那份
10/08 19:30, 4F

10/08 19:31, , 5F
指標, 並不會改到別人的那份, 所以這樣的判斷沒有幫助
10/08 19:31, 5F
文章代碼(AID): #1Cha3ytR (C_and_CPP)
文章代碼(AID): #1Cha3ytR (C_and_CPP)