Joh*_*ell 16 c++ optimization move-semantics c++11
鉴于一个类实际上是可移动的,手动实现移动构造函数和移动类的赋值运算符很快变得乏味.
我想知道什么时候这样做实际上是一个沉重,沉重,过早的优化?
例如,如果一个类只有普通的POD数据或者它们自己有移动构造函数和移动赋值运算符定义的成员,那么我猜测编译器将只是优化该批次的狗屎(在POD的情况下)和否则使用成员的移动构造函数和移动赋值运算符.
但这有保证吗?在什么情况下,我应该想到明确需要实现一个移动构造函数和移动赋值操作符?
编辑:正如他在回答评论下面提到的尼科尔流星锤/sf/answers/697627381/,与Visual Studio 11 Beta版(之前)没有转移构造函数或移动赋值操作符是不断自动生成.参考:http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
如果你发现自己实施,任何:
然后你应该问自己是否需要实施移动构造.如果您"=默认"上述任何一项,您应该问自己是否应该"=默认"移动成员.
更重要的是,您应该记录并测试您的假设,例如:
static_assert(std::is_nothrow_default_constructible<A>::value, "");
static_assert(std::is_copy_constructible<A>::value, "");
static_assert(std::is_copy_assignable<A>::value, "");
static_assert(std::is_nothrow_move_constructible<A>::value, "");
static_assert(std::is_nothrow_move_assignable<A>::value, "");
static_assert(std::is_nothrow_destructible<A>::value, "");
Run Code Online (Sandbox Code Playgroud)
首先,移动语义只对包含任何类型资源的类有帮助."扁平"课程根本无法从中受益.
接下来,你应该建立你的班列"积木"一样的vector
,unique_ptr
和喜欢,所有的处理资源的事实真相低层次的细节.如果您的类是这样完成的,那么您将不必编写任何内容,因为编译器将为您正确生成成员.
如果你需要为日志记录编写析构函数,那么移动ctors的生成将被禁用,因此你需要一个T(T&&) = default;
支持它的编译器.否则,这是自己写这样一个特殊成员的唯一地方之一(好吧,除非你写这样一个"积木").
请注意,析构函数和构造函数中的日志记录可以更简单地完成.只需继承一个记录构造/销毁的特殊类.或者使它成为成员变量.接着就,随即:
tl; dr让编译器为您生成特殊成员.这也算复制构造函数和赋值运算符,以及析构函数.不要自己写那些.
(好吧,也许是赋值操作符,如果你可以将它们识别为瓶颈并想要优化它们,或者如果你想要特殊的异常安全或者某些东西.虽然,"构建块"应该已经提供了所有这些.)