Re: [問題] special function覺得困惑

看板C_and_CPP作者 (A-So)時間7年前 (2018/10/06 06:48), 7年前編輯推噓2(208)
留言10則, 3人參與, 7年前最新討論串2/2 (看更多)
※ 引述《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

10/06 07:28, 7年前 , 1F
我了解RVO不是一定有, 但你拿我的範例跑在c++17以上
10/06 07:28, 1F

10/06 07:28, 7年前 , 2F
甚至VC, 他還是一樣的行為.
10/06 07:28, 2F

10/06 07:28, 7年前 , 3F
而且比較糾結的是 竟然是因為差異在有沒有刻意"定義"
10/06 07:28, 3F

10/06 07:29, 7年前 , 4F
copy 或是 move constructor 實在很詭異
10/06 07:29, 4F

10/06 07:31, 7年前 , 5F
尤其是POD type, 我還要"刻意"寫copy/move{} 才會有RVO?
10/06 07:31, 5F
這個可能要花時間查查或直接問compiler實做細節 對我來說copy elision就是一個compiler optimization 是個不強求的東西XD

10/06 07:31, 7年前 , 6F
4. 有文章講這個嗎? 因為被人家指證貼了rule of five要
10/06 07:31, 6F

10/06 07:32, 7年前 , 7F
叫我把interface補上其他special function 要想辦法反駁
10/06 07:32, 7F
沒耶這只是我把自己對OO跟rule of five的理解拿來解釋為什麼interface class只寫 virtual destructor = default就夠了,既然無法建立object所以其他都是多寫的 ※ 編輯: boy770329 (80.57.62.150), 10/07/2018 04:06:44

10/07 12:52, 7年前 , 8F
interface class提供預設實作是沒問題的喔
10/07 12:52, 8F

10/07 12:52, 7年前 , 9F
Java現在也可以這麼做了
10/07 12:52, 9F

10/07 15:11, 7年前 , 10F
他是delete compiler implicit產生的實做吧?
10/07 15:11, 10F
文章代碼(AID): #1Rj-ehlP (C_and_CPP)
文章代碼(AID): #1Rj-ehlP (C_and_CPP)