看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《masan22305 (海豹)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : Windows codeblock12.11 GCC 4.7.1 : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : no : 程式碼(Code):(請善用置底文網頁, 記得排版) : Q1: http://ideone.com/qhnWs8 : Q2: http://ideone.com/szu4Jh 首先這兩支程式有兩個共同的問題: 1) new char[...] 的時候要多留一格用來存 '\0' 所以 A(const char* str) 裡要用 new char[strlen(str) + 1] Q1 裡的 A(const A& a) 裡要用 new char[strlen(str) + 2] 2) 實作 copy constructor 的時候, 同時要實作 destructor 和 operator= 事實上如果你有實做 operator= 同時印出訊息的話應該看得出發生什麼事 : ------------------------------------------------------------- : 問題1: : 為什麼vector中呼叫destructor的順序 : 跟一般物件呼叫destructor的順序不同? : 物件不是會保持"後進先出"的原則嗎? 不是: vector 只是可變動大小陣列, 保証 destruct 時會 destruct 所有內容 要從 [0] 跑到 [n-1] 還是反過來沒有規定. : 問題2: : 為什麼Avec.erase(iter)呼叫到的destructor竟然是 : ~A() called and cptr is 3? : iter現在指到的物件不是應該是a1嗎? : 接下去的destructor順序雖然a1似乎是不見了 : 但是a3的內容似乎也被delete掉了 因為 erase(iter) 時 iter 指到的是 [0] vector 的記憶體管理比較僵硬 (跟 deque 相比), 一定要用 [0] .. [n-1] 不能用 [1] .. [n] 所以現在有 data[0].ptr = "1"; data[1].ptr = "2"; data[2].ptr = "3" erase([0]) 的時候 vector 必需 data[0] = data[1]; data[1] = data[2]; data[2].~A(); 於是就看到 "3" 被 destruct 了 然後再看看 destruct 這個 vector 時發生了什麼事? data[0].~A(); => cptr = "2" data[1].~A(); => cptr ~~~> "3" ? 但是剛剛 data[2].~A(); 的時候就已經把這個 cptr destruct 掉了 所以就 undefined behavior 了 --- 總結: 實作 copy constructor 時, 一定要同時實作 destructor 和 operator= : -------------------------------------------------------------- : 以上兩個新手問題還請各位大大幫忙!! -- A man may die, countries may rise and fall, but an idea lives on. - John F. Kennedy -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 128.36.232.45
masan22305:new那邊是我沒想清楚~感謝提醒 06/06 19:10
masan22305:感謝s詳細的解釋 對vector的運作又更清楚了 謝謝! 06/06 19:12
masan22305: *s大 06/06 19:17
LPH66:這個結論有個名詞叫 Rule of three 寫了其中一個則三個都要 06/06 22:34
LPH66:http://tinyurl.com/694gwf 06/06 22:36
masan22305:以前雖然有聽過 但是沒什麼深刻的體會 現在終於懂了XD 06/08 00:09
BlazarArc:順便想問, 一個class如果有dtor, 而不能被copy, 算遵守 06/08 02:46
BlazarArc:Rule of three 嗎? 06/08 02:47
scwg:不能 copy 等於是實作 private operator= 和 copy ctor不是嘛 06/08 02:58