何时复制和交换习语不适用

时间:2015-11-16 11:59:57

标签: c++ copy-and-swap

在阅读this关于复制和交换习语的内容后,我已阅读this,其中包含(2):

yourImageView.image = [NSUserDefaults standardUserDefaults] ObjectForKey:"myImage"];
  

(2)复制赋值运算符的典型声明   复制和交换习语无法使用

我们什么时候应该避免使用复制和交换习惯用法?

当它"不能使用"共?

是否存在真实生活情况,即复制和交换以及零规则都不适用?

我确实找到了这个question,但它太具体了,没有包含任何关于如何识别此类案例的指南。

2 个答案:

答案 0 :(得分:7)

  

我们何时应该避免使用复制和交换习惯用法?

当您能够证明天真副本比swap更安全且更快时。

当没有拥有对象的成员指针(既不是智能指针也不是原始指针)时,您可以识别所有成员对象的情况。

  

什么时候“完全不能使用”?

当类型不是swappable时,不能使用复制和交换。

要进行交换,类型必须是可移动构造和可移动分配,或者您必须已定义swap成员函数或友元函数。

答案 1 :(得分:2)

描述class_name& class_name::operator=(class_name)的赋值运算符的潜在实现的链接为:

  

可以使用复制和交换习惯用法时复制赋值运算符的典型声明

并且class_name& class_name::operator=(const class_name&)为:

  

无法使用复制和交换习惯用法时复制赋值运算符的典型声明

基本上我们总是希望尽可能使用copy-and-swap,如excellent answer to your linked question中所述,因为它将通过自我指派测试。

所以现在问题是为什么公约在http://www.cppreference.com上提到了?

让我们说我正在为一个虚拟类实现一个复制构造函数,我想向任何继承他们应该使用复制和交换习惯用法的人说清楚。我该怎么办?我可以通过在初始调用中为他们复制来帮助他们:

class_name& class_name::operator=(class_name)

这是一个按值复制的,所以任何子类的实现者都会看到我已经为他们制作了副本,所以他们需要做的只是交换。

现在,如果我的class_name包含一个无法复制构造的成员,例如,如果我的类有一个unique_ptr使得它不能被复制构造,该怎么办?我可以通过 not 通过赋值运算符的value参数进行指示,例如:

class_name& class_name::operator(const class_name&)

表明它将在任何子类的实现者上,以确保进行足够的检查以通过自我指派测试。