我好像不明白你为什么要用move assignment operator
CLASSA & operator=(CLASSA && other); //move assignment operator完毕,copy assignment operator
CLASSA & operator=(CLASSA other); //copy assignment operatormove assignment operator只接受一个r-value reference。
CLASSA a1, a2, a3;
a1 = a2 + a3;在copy assignment operator中,other可以是使用copy constructor或move constructor的构造函数(如果other是用rvalue初始化的,则可以移动-构造--如果定义了move-constructor )。
如果是copy-constructed,我们将执行1次复制,而该副本是无法避免的。
如果是move-constructed,那么其性能/行为与第一个重载所产生的性能/行为相同。
我的问题是:
1-为什么要实现move assignment operator。
2-如果other是从r值构造的,那么编译器将选择调用哪个assignment operator?为什么?
发布于 2014-11-06 08:52:37
你不是在跟我比
如果您正在编写像std::unique_ptr这样的只移动类型,那么移动赋值运算符将是您唯一的选择。
更典型的情况是,您有一个可复制的类型,在这种情况下,我认为您有三个选择。
T& operator=(T const&)T& operator=(T const&)和T& operator=(T&&)T& operator=(T)与移动请注意,您在一个类中建议的这两个重载都不是一个选项,因为它是不明确的。
选项1是传统的C++98选项,在大多数情况下执行得很好。但是,如果您需要优化r值,您可以考虑选项2并添加一个移动赋值操作符。
这是诱人的考虑选项3和传递的价值,然后移动,我认为这是你的建议。在这种情况下,您只需编写一个赋值运算符。它接受l-值,只需额外移动一次就可以接受r-值,许多人都会提倡这种方法。
然而,Herb在2014年的“回到基础!现代C++风格的要点”演讲中指出,这一选择是有问题的,而且可能会慢得多。在l-值的情况下,它将执行一个无条件的副本,不会重用任何现有的容量。他提供数字来支持他的主张。唯一的例外是没有可重用的现有能力的构造函数,而且您通常有许多参数,因此传递值可以减少所需的重载数。
因此,我建议您从选项1开始,如果需要优化r值,则移到选项2。
发布于 2014-11-06 06:10:42
显然,这两种超载并不等同:
T const& )。当然,对于只移动的类型,比如std::unique_ptr<T>,定义这个赋值运算符是合适的选择.swap()将对象的状态从右侧替换为状态。它的优点是,参数的复制/移动结构常常可以被省略。在任何情况下,您都不希望两个重载都在一个类中!显然,当从lvalue赋值时,会选择使用值的版本(另一个选项不可行)。然而,在分配rvalue时,这两种赋值运算符都是可行的,也就是说,将出现模糊。通过尝试编译以下代码,可以很容易地验证这一点:
struct foo
{
void operator=(foo&&) {}
void operator=(foo) {}
};
int main()
{
foo f;
f = foo();
}要单独处理移动和复制构造,可以使用T&&和T const&作为参数定义一对赋值操作符。然而,这导致必须实现两个版本的本质上相同的副本分配,而只有一个T作为参数时,只需要实现一个副本赋值。
因此,有两个明显的选择:
T::operator= (T&&)。T::operator=(T)。https://stackoverflow.com/questions/26772146
复制相似问题