在自我分配期间,复制和交换习语如何工作?
Posted
技术标签:
【中文标题】在自我分配期间,复制和交换习语如何工作?【英文标题】:How does the copy-and-swap idiom work during self-assignment? 【发布时间】:2011-04-26 07:57:06 【问题描述】:我正在阅读优秀的copy-and-swap idiom 问题和答案。但是我没有得到一件事:在自我分配的情况下它是如何工作的?示例中提到的对象other
不会释放分配给mArray
的内存吗?那么被自赋值的对象不会有一个无效的指针吗?
【问题讨论】:
【参考方案1】:但是我不明白的一件事是在自我分配的情况下它是如何工作的?
让我们看一个简单的案例:
class Container
int* mArray;
;
// Copy and swap
Container& operator=(Container const& rhs)
Container other(rhs); // You make a copy of the rhs.
// This means you have done a deep copy of mArray
other.swap(*this); // This swaps the mArray pointer.
// So if rhs and *this are the same object it
// does not matter because other and *this are
// definitely not the same object.
return *this;
通常您将上述实现为:
Container& operator=(Container other)
// ^^^^^^^^ Notice here the lack of `const &`
// This means it is a pass by value parameter.
// The copy was made implicitly as the parameter was passed.
other.swap(*this);
return *this;
示例中提到的其他对象不会释放分配给 mArray 的内存吗?
该副本制作 mArray 的深层副本。 然后我们用 this.mArray 交换。当其他超出范围时,它会释放 mArray(如预期的那样),但这是它自己的唯一副本,因为我们在执行复制操作时进行了深层复制。
那么,自分配的对象最终不会有一个无效的指针吗?
没有。
【讨论】:
哎呀..我错过了复制ctor中的深层副本..感谢您的解释。 旧帖子,但我仍然有同样的疑问.. 与if (this == &other) return *this;
相比,在使用复制交换习语时进行自我分配的开销是不是太大了?
@Hummingbird:在有自分配的情况下会有更多的开销。 BUT 自赋值极为罕见(在实际代码中非常小)。如果你反过来看。如果您正在优化代码以进行自分配,那么您正在对正常操作的代码感到失望。现在,正常操作是如此普遍,以至于它实际上可以产生可衡量的差异(人们已经做到了这一点)。我愿意在极少发生的情况下支付额外的成本,以在非常频繁发生的情况下获得最佳代码。以上是关于在自我分配期间,复制和交换习语如何工作?的主要内容,如果未能解决你的问题,请参考以下文章