对于课程A
,我们可以使用
A& operator=( A other ) { /* ... */ }
而不是
A& operator=( const A& other ) { /* ... */ }
A& operator=( const A&& other ) { /* ... */ }
没有恶化表现或其他负面影响?
答案 0 :(得分:6)
实际上,您可以使用
实现复制和交换RewriteRule
对于复制和移动分配,但自我赋值运算符的无条件复制将降低性能。
除了以上功能不能被标记为移动应该是轻量级的,便宜的,它不是必需的,但它应该是轻量级的。因此,移动构造函数/赋值应为A& operator=( A other ) { swap(other, *this); return *this; }
,noexcept
。如果没有noexcept
移动构造函数/赋值运算符,则在容器增长时无法调用move_if_noexcept
,容器将返回复制。
因此,推荐的方法是:
noexcept
答案 1 :(得分:5)
没有恶化表现或其他负面影响?
这取决于A
的数据成员和基类,甚至可以取决于A的基础和成员的基础和成员。
以下链接指向视频的一部分,该视频演示如果A
有vector
作为数据成员,那么复制/交换习惯用品可能会导致 70%的性能损失,用于平均的复制赋值运算符。这与更简单的默认任务特殊成员的方法相比较。
http://www.youtube.com/watch?v=vLinb2fgkHk&t=35m30s
class A
{
std::vector<int> v_;
public:
// ...
};
您可以期望string
数据成员与vector
数据成员具有相同的影响。
如果您不确定自己的A
,并且性能对您来说很重要,请尝试两种方法并进行衡量。这正是视频中所展示的内容。
答案 2 :(得分:4)
“移动”环境的表现可能会受到轻微影响。
如果您的类A
是可移动的,那么在移动上下文中,按值传递的复制和交换实现将按两个操作的顺序实现移动:
other
的移动构造函数将右侧(RHS)值移动到参数A
。other
移至*this
(或与other
交换*this
。第二个实现(使用专门的移动分配)可以在一个操作中执行相同的操作:它将直接使用*this
移动(或交换)右侧值。
因此,可能,复制和交换变体涉及额外移动的开销。
“复制”环境的表现可能会受到轻微到严重的影响。
如果您的左侧(LHS)有一些可复制的内部资源(如内存块),可以容纳相应的RHS值而无需重新分配,那么专用的复制分配实现只需要从RHS资源复制数据到LHS资源。不需要内存分配。
在copy-and-swap变体中,无条件地创建副本,并且必须无条件地分配和释放上述内部资源。这会对性能产生重大负面影响。