使用哪个:移动分配运算符与复制分配运算符 [英] Which to use: move assignment operator vs copy assignment operator

查看:105
本文介绍了使用哪个:移动分配运算符与复制分配运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎不明白为什么要使用移动赋值运算符

I don't seem to get why would you use the move assignment operator:

CLASSA & operator=(CLASSA && other); //move assignment operator

移到复制赋值运算符

CLASSA & operator=(CLASSA  other); //copy assignment operator






The 移动赋值运算符仅采用 r值引用,例如

CLASSA a1, a2, a3;
a1 = a2 + a3;

副本分配运算符中, other 可以是 copy构造器 move构造器(如果 other 用右值初始化,则可以移动构造-如果 move-constructor 已定义-) 。

In the copy assignment operator, other can be constructor using a copy constructor or a move constructor (if other is initialized with an rvalue, it could be move-constructed --if move-constructor defined--).

如果它是复制构建的,我们将复制1个副本,并且该副本将不可避免。

If it is copy-constructed, we will be doing 1 copy and that copy can't be avoided.

如果它是移动构造的,则其性能/行为与第一次重载所产生的性能/行为相同。

If it is move-constructed then the performance/behavior is identical to the one produced by the first overload.

我的问题是:

1-为什么要实施移动赋值运算符

1- Why would one want to implement the move assignment operator.

2-如果 other 是根据r值构造的,则该赋值运算符编译器会选择调用吗?为什么?

2- If other is constructed from an r-value then which assignment operator would the compiler choose to call? And why?

推荐答案

您没有在比较相像

如果您正在编写仅移动类型,例如 std :: unique_ptr ,那么移动赋值运算符将是您唯一的选择。

If you are writing a move-only type like std::unique_ptr then a move assignment operator would be your only choice.

更典型的情况是您拥有可复制的类型,在这种情况下,我认为您有三个选择。

The more typical case is where you have a copyable type in which case I think you have three options.


  1. T& operator =(T const&)

  2. T& operator =(T const&) T&运算符=(T&&)

  3. T&运算符=(T)并移动

  1. T& operator=(T const&)
  2. T& operator=(T const&) and T& operator=(T&&)
  3. T& operator=(T) and move

请注意,在一类中同时具有您建议的重载并不是

Note that having both the overloads you suggested in one class is not an option as it would be ambiguous.

选项1是传统的C ++ 98选项,在大多数情况下效果会很好。但是,如果您需要针对r值进行优化,则可以考虑选择2并添加一个移动赋值运算符。

Option 1 is the traditional C++98 option and will perform fine in most cases. However, if you need to optimize for r-values you could consider Option 2 and add a move assignment operator.

很容易考虑选择3并通过-值,然后移动,我认为这是您的建议。在这种情况下,您只需要编写一个赋值运算符。它接受l值,而仅需付出一个额外的举动即可接受r值,许多人会提倡这种方法。

It is tempting to consider Option 3 and pass-by-value and then move which I think is what you are suggesting. In that case you only have to write one assignment operator. It accepts l-values and at the cost of only one extra move accepts r-values and many people will advocate this approach.

但是,赫伯·萨特(Herb Sutter)在他的回到基础知识!现代C ++风格的要点 谈到该选项存在问题,并且速度可能慢得多。对于l值,它将执行无条件复制,并且不会重用任何现有容量。他提供数字来备份他的要求。唯一的例外是没有现有重用能力的构造函数,并且您经常有很多参数,因此按值传递可以减少所需的重载次数。

However, Herb Sutter pointed out in his "Back to the Basics! Essentials of Modern C++ Style" talk at CppCon 2014 that this option is problematic and can be much slower. In the case of l-values it will perform an unconditional copy and will not reuse any existing capacity. He provides numbers to backup his claims. The only exception is constructors where there is no existing capacity to reuse and you often have many parameters so pass by-value can reduce the number of overloads needed.

所以我会建议您从选项1开始,如果需要优化r值,则转到选项2。

So I would suggest you start with Option 1 and move to Option 2 if you need to optimize for r-values.

这篇关于使用哪个:移动分配运算符与复制分配运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆