[問題] operator=裡呼叫destructor

看板C_and_CPP作者 (Caesar)時間11年前 (2014/11/22 22:29), 11年前編輯推噓2(2015)
留言17則, 6人參與, 最新討論串1/4 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VC++ 問題(Question): 我之前都會在右值的operator=裡面呼叫自己的destructor 直到我寫了類似底下的code(真正的code裡面是unordered_map),發現如果將 this->~A();替換成 for_each(vec.begin(),vec.end(),[](int* &val){delete val;}); 在VC++上執行就不會有問題(不過在Ideone上面,兩個版本都是正確執行的) 之所以會這麼做,是因為假設會有很多個vector,那我每個都要做delete實在是太麻煩了 所以乾脆呼叫自己的destructor,省去這些code(就是我懶的意思) 我不想用unique_ptr,因為這個A會有複製的行為,unique_ptr不符合我的要求,而且我 也不想用get() 再來,我找到以下這兩個網址 http://ppt.cc/X43Y http://ppt.cc/FfXf 照這樣看起來,好像這是undefined behavior 而Effective C++ 2e裡面的條款33說明,constructor或destructor裡面通常會多放一些 code(雖然那篇是講inline) 我在想是不是"這些code"導致我這樣呼叫會錯 但是我之前寫都沒有問題,所以我要問的就是 1.請問我這樣寫,到底是不是undefined behavior? 2.手動呼叫destructor,就算underfined behavior? 3.承上,如果是,那這樣我就需要額外寫一個clear(),做記憶體釋放,對吧? 4.承2,如果不是,那為甚麼原本的code不行? 5.另外,如果我的data只有一個pointer,而不是container<pointer>這種的,那我這樣 寫,是對的嗎? (因為我之前好像沒有寫過放在container的,所以之前的code都沒有出問題過,但因為 是undefined behavior,所以碰巧沒問題?) 程式碼(Code):(請善用置底文網頁, 記得排版) #include<algorithm> #include<vector> using namespace std; class A { vector<int*> vec; public: A(){} A& operator=(A &&rVal) { if(this!=&rVal) { this->~A(); vec=move(rVal.vec); } return *this; } ~A() { for_each(vec.begin(),vec.end(),[](int* &val){delete val;}); } }; int main() { A a; a=A(); } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 142.162.239.243 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1416666550.A.F30.html

11/22 22:43, , 1F
與問題無關,沒看過reference to reference的用法(A &&rVal)
11/22 22:43, 1F

11/22 22:45, , 2F
另外reference to pointer應該不需要(int* &val)
11/22 22:45, 2F

11/22 22:47, , 3F
忘了說,好有趣的寫法和思維
11/22 22:47, 3F
的確不需要referenece,加上reference只是我個人的習慣 推 littleshan: && 是 rvalue reference 啦 11/22 23:13

11/22 23:15, , 4F
除非你用了placement new, 否則自己呼叫dtor幾乎都是
11/22 23:15, 4F

11/22 23:16, , 5F
錯誤設計。以這個例子來說,你根本不需要去delete
11/22 23:16, 5F

11/22 23:16, , 6F
阿是...原來如此
11/22 23:16, 6F

11/22 23:17, , 7F
回 && 那個
11/22 23:17, 7F

11/22 23:18, , 8F
只需要寫vec.swap(rVal.vec)就夠了
11/22 23:18, 8F

11/22 23:19, , 9F
因為rVal馬上就會被解構了,讓它的解構式來處理就好
11/22 23:19, 9F
如果將move assignment改成是copy assignment呢?

11/22 23:54, , 10F
ls你講的對...,我糊塗了。
11/22 23:54, 10F

11/22 23:55, , 11F
就不需要自己寫 copy ass. 因為 A 的資料成員內沒有 ptr
11/22 23:55, 11F

11/22 23:59, , 12F
copy assignment 就用 copy & swap idiom 就好了
11/22 23:59, 12F
感謝firose的關鍵字,我以前一直以為swap *this是一件不行的事情 但是我現在卻遇到,如果不用copy & swap idiom就會失敗的情況,明明code都跟destructor裡的一樣阿!!! ※ 編輯: Caesar08 (142.162.239.243), 11/23/2014 00:57:18

11/23 01:29, , 13F
借題問下, 呼叫 destructor 後, 是不是物件相當已經消滅,
11/23 01:29, 13F

11/23 01:29, , 14F
如果沒用 placement new 重新生一個出來, 直接用 (move)
11/23 01:29, 14F

11/23 01:30, , 15F
assignment operator 是未定義行為呢?
11/23 01:30, 15F

11/23 12:58, , 16F
如果照我想的話,是物件裡面的東西已經消滅,但物件沒有
11/23 12:58, 16F

11/23 12:59, , 17F
所以move assignment operator不會是undefined behavior
11/23 12:59, 17F
文章代碼(AID): #1KS9ssym (C_and_CPP)
文章代碼(AID): #1KS9ssym (C_and_CPP)