看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《lovejomi (JOMI)》之銘言: : 一切是因為看到這篇文章 : https://quuxplusone.github.io/blog/2018/07/07/defaulted-destructor-inhibits-mo : ve/ : 覺得有趣 然後測試了一下 : https://ideone.com/B2ZuZf : 的確真的是這樣.... : 但這問題令我很困惑 : 我知道這些special function有implicit compiler幫產生 或是 會被implicit delete.. : . : 0.對我來講 "有" or "被delete" 二選一 但這是例外? 還是情況(規則)比我想像的更是 : 複雜許多 這個我看不懂問題是甚麼... : 1. 為什麼這情況 move會整個"失效", 但 is_move_constructible顯示 true? 因為有define destructor, 自然沒有move constructor https://en.cppreference.com/w/cpp/types/is_move_constructible 請看Note部分,沒有move constructor但有copy constructor的情況下也是true : 接著測試RVO相關 : https://ideone.com/xTWkSJ : 詭異了....這三組乍看可以說是一樣的 但....結果只有Foo 可以RVO : 於是試著歸納目前的結果 : 2. 只要class 有寫 move or copy 只要擇一不是default (就是{空}) , RVO就會發生 : 如 https://ideone.com/iByEyO : 如果RVO能不能做到取決於是不是寫default 根本沒道理啊? : 這樣pod struct 看來是無法 rvo? : 以上實在是讓我一頭霧水 : 我用VC 測試結果竟也一樣(難道是standard 規範?) : 最後得到一個結論 : 因為=default 跟 {} 經驗顯示 不是完全相等(cstr / dstr) : 而且似乎依照以上實驗可以說{} 比寫=default更穩 建議先去了解copy elision RVO是其中一種,基本上到C++17才有規範標準做copy elision 在那之前都是compiler自己爽怎麼做就怎麼做,所以寫code本來就不該假設RVO會發生 只是有一些RVO一定不會發生的情況要自己小心 : 3. 是不是我可以說 要寫一個完美的class 請遵守 rule of five : + special function若是default行為請把 定義跟宣告分開(說真的沒看過這樣寫) 或 : 是能用{}就用{} : 如 https://ideone.com/14mLze (這樣就會RVO) rule of five應該只是一個寫class的基本,避免漏掉某些情況之後用這class出問題 : 提到rule of five : 4. 想順便問一下 如果定義一個 interface class : "通常" 大家會怎麼寫? : 如果遵守rule of five : 會變成這樣 https://ideone.com/cm6rkb : 但總覺得通常看到的寫法會是直接 : class Interface : { : public: : virtual ~Interface() = default; : } 基本上就只寫virtual destructor = default; 跟其他pure virtual functions 定義virtaul destructor是為了建立virtual table在delete物件可以砍到對的那個 Interface class不需要管copy/move constructor/assign operator 因為他有pure virtual method所以你只能透過pointer/reference操作這個物件 既然不能建立一個object, 也代表你沒辦法真的copy或是move他 所以對這個pointer或reference實際指到的記憶體區塊copy跟move都不重要 : 請問我要怎麼取捨呢? : 謝謝 有錯請幫指出,有段時間沒唸C++了靠自己印象跟google稍微回一下 建議可以看Effective Modern C++,提到蠻多的但是我怕有的東西我記錯 有一些特例規定像是沒有move constructor時compiler會拿copy constructor去擋一下 或是定義destructor後只有delete move系列functions而沒有一起delete copy的 主要還是避免Legacy codes因為C++改版編不過會[很頭痛 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 80.57.62.150 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1538779691.A.BD9.html
lovejomi: 我了解RVO不是一定有, 但你拿我的範例跑在c++17以上 10/06 07:28
lovejomi: 甚至VC, 他還是一樣的行為. 10/06 07:28
lovejomi: 而且比較糾結的是 竟然是因為差異在有沒有刻意"定義" 10/06 07:28
lovejomi: copy 或是 move constructor 實在很詭異 10/06 07:29
lovejomi: 尤其是POD type, 我還要"刻意"寫copy/move{} 才會有RVO? 10/06 07:31
這個可能要花時間查查或直接問compiler實做細節 對我來說copy elision就是一個compiler optimization 是個不強求的東西XD
lovejomi: 4. 有文章講這個嗎? 因為被人家指證貼了rule of five要 10/06 07:31
lovejomi: 叫我把interface補上其他special function 要想辦法反駁 10/06 07:32
沒耶這只是我把自己對OO跟rule of five的理解拿來解釋為什麼interface class只寫 virtual destructor = default就夠了,既然無法建立object所以其他都是多寫的 ※ 編輯: boy770329 (80.57.62.150), 10/07/2018 04:06:44
thefattiger: interface class提供預設實作是沒問題的喔 10/07 12:52
thefattiger: Java現在也可以這麼做了 10/07 12:52
boy770329: 他是delete compiler implicit產生的實做吧? 10/07 15:11