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