提问人:24n8 提问时间:2/28/2020 最后编辑:xskxzr24n8 更新时间:2/28/2020 访问量:514
在复制赋值运算符中按值传递与按引用传递
Pass by value vs. pass by reference in copy assignment operator
问:
首先,有一个类似的热门帖子 什么是复制和交换成语?. 接受的答案有一个指向 https://web.archive.org/web/20140113221447/http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ 的链接。
接受的页面和链接的页面都声明复制分配运算符的常用实现是(从上一个链接复制和粘贴)
T& T::operator=(T const& x) // x is a reference to the source
{
T tmp(x); // copy construction of tmp does the hard work
swap(*this, tmp); // trade our resources for tmp's
return *this; // our (old) resources get destroyed with tmp
}
但是那
T& operator=(T x) // x is a copy of the source; hard work already done
{
swap(*this, x); // trade our resources for x's
return *this; // our (old) resources get destroyed with x
}
由于编译器的复制省略优化,或者通常,始终按值传递而不是通过引用传递,然后复制通过引用传递的参数,因此效果更好。
我同意第二种选择与第一种相同或更好,但并不差,但我感到困惑的是,为什么第一种选择一开始就是这样写的。我不明白为什么需要临时变量和交换。
相反,我们不能做这样的事情吗:
T& T::operator=(T const& x) // x is a reference to the source
{
this->member_var = x.member_var;
//if we have to do a deep copy of something, implement that here
return *this;
}
它不使用复制构造函数。
答:
2赞
xskxzr
2/28/2020
#1
如果有多个成员,则赋值运算符不是异常安全的:
T& T::operator=(T const& x)
{
this->member_var1 = x.member_var1;
this->member_var2 = x.member_var2; // if an exception occurs here, this->member_var1 will still be changed
return *this;
}
评论
2赞
ShadowRanger
2/28/2020
这与线程安全无关(如果没有同步,多成员交换也不是神奇的“安全”;几乎任何在没有同步或原子的情况下读取数据的尝试都可能读取垃圾,尤其是在具有弱有序内存模型的系统上,或者由于撕裂),而是关于强大的异常保证。
上一个:交换数组中的元素导致问题
评论
this
swap
noexcept
swap
operator=
x
foo = std::move(bar)
foo::operator=(foo x)
x
bar
x
*this
x
std::move(bar)
x
是左值表达式,与任何其他命名变量一样。它有一个名称 (),你可以取它的地址 ()。它的构造方式不会改变它的价值类别。x
&x
T x;
x
T function();
x = function();
function()
x