繁体   English   中英

C++:赋值运算符:按值传递(复制和交换)与按引用传递

[英]C++: assignment operator: pass-by-value (copy-and-swap) vs pass-by-reference

考虑到复制和交换习语的优点......

为什么我们仍然需要接受引用作为主流的复制赋值运算符?

class T {
public:

    // 1: Why still commonly this?
    T& operator=(const T& rhs);

    // 2: Why not mostly that?
    T& operator=(T rhs);
}

有答案建议使用后者(此处此处)。

但是,大多数 SO 示例仍然围绕 pass-by-reference operator=

甚至合并 C++ 常见问题解答指出(是的,它是关于const ,但是......):

A class Fred的复制构造函数和赋值运算符应在参数中具有const :分别为Fred::Fred(const Fred&)Fred& Fred::operator=(const Fred&)

显然,复制和交换是可以通过引用传递来实现的——如果无论如何都要进行复制,那就没有必要了。 人们可能还想避免在调用时立即复制(在正文中有条件地执行它)——那不是不太常见的情况(可能是过早的优化)吗?

不应该使用按值传递的复制和交换作为默认方法吗?

通过引用传递是为了在您需要更快的执行时避免不必要的复制,而通过 const 引用传递是当您想要快速和只读地传递它时。 并且通过副本是当您想要复制 object 以便能够在 function 的执行/实施过程中对其进行操作。

除了创建虚假的无用副本之外,第二个选项可能不适用于每个 class,因为复制可能会被删除。

第一个选项有很多(如果不是全部)优点:无副本、只读语义、始终可用。

我被指出了有价值的提示

例如,有没有想过为什么高性能/经常使用的 std::types 像std::vectorstd::string不使用复制/交换? | 霍华德·欣南特

我发现的所有反对 copy-on-swap 的都是关于优化(避免复制,重新利用lhs ):

  • 显然,自分配是无用的。
  • lhsrhs空间时,另一种常见的可能性发生在 (STL)容器中:

     class container<T> { public: // If passed by value, created copy would unconditionally increase capacity: T& operator=(const container<T>& rhs) { //... if (this->capacity() >= rhs.size()) { // reuse capacity... } else { // increase capacity... } } }

    请注意,提示还提到了 (STL)容器

operator=的权衡是:

  • 按价值 + 复制和交换:通过强大的异常保证简化(节省人力时间)
  • 通过参考:允许优化(节省机器时间)可能削弱保证

相关答案:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM