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

作者: boy770329 (A-So)   2018-10-06 06:48:03
※ 引述《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++改版編不過會[很頭痛
作者: lovejomi (JOMI)   2018-10-06 07:28:00
我了解RVO不是一定有, 但你拿我的範例跑在c++17以上甚至VC, 他還是一樣的行為.而且比較糾結的是 竟然是因為差異在有沒有刻意"定義"copy 或是 move constructor 實在很詭異尤其是POD type, 我還要"刻意"寫copy/move{} 才會有RVO?4. 有文章講這個嗎? 因為被人家指證貼了rule of five要叫我把interface補上其他special function 要想辦法反駁
作者: thefattiger (LT)   2018-10-07 12:52:00
interface class提供預設實作是沒問題的喔Java現在也可以這麼做了
作者: boy770329 (A-So)   2018-10-07 15:11:00
他是delete compiler implicit產生的實做吧?

Links booklink

Contact Us: admin [ a t ] ucptt.com