c++ - 根据复制操作符或单独执行复制操作符?

标签 c++ copy-assignment

这不是 Implementing the copy constructor in terms of operator= 的拷贝但这是一个更具体的问题。 (或者我喜欢这样想。)

简介

给定一个这样的(假设的)类:

struct FooBar {
  long id;
  double valX;
  double valZ;
  long   valN;
  bool   flag; 
  NonCopyable implementation_detail; // cannot and must not be copied

  // ...
};

我们不能通过默认生成的函数复制它,因为您既不能复制构造也不能复制 NonCopyable 对象。然而,对象的这一部分是我们实际上对复制不感兴趣的实现细节。

为此编写交换函数也没有任何意义,因为交换函数只能复制 std::swap 所做的(减去 NonCopyable)。

因此,如果我们想要复制这些对象,我们只能自己实现复制构造器和复制运算符。这只需分配其他成员即可轻松完成。

问题

如果我们需要实现复制构造函数和操作符,我们应该根据复制操作符来实现复制构造函数,还是应该用初始化列表“复制”代码?

即给定:

FooBar& operator=(FooBar const& rhs) {
  // no self assignment check necessary
  id = rhs.id;
  valX = rhs.valX;
  valZ = rhs.valZ;
  valN = rhs.valN;
  flag = rhs.flag;
  // don't copy implementation_detail
  return *this;
}

我们应该写a)

FooBar(FooBar const& rhs) {
  *this = rhs;
}

或b)

FooBar(FooBar const& rhs)
: id(rhs.id)
, valX(rhs.valX)
, valZ(rhs.valZ)
, valN(rhs.valN)
, flag(rhs.flag)
// don't copy implementation_detail
{ }

答案的可能方面是性能、可维护性和可读性。

最佳答案

通常您根据复制构造函数(@Roger Pate 的版本)实现赋值运算符:

FooBar& operator=(FooBar copy) { swap(*this, copy); return *this; }
friend void swap(FooBar &a, FooBar &b) {/*...*/}

这需要提供一个 swap 函数来交换相关成员(在您的情况下除了 implementation_detail 之外)。

如果 swap 不抛出此方法,则保证对象不会处于某些不一致的状态(仅分配了部分成员)。

但是在您的情况下,因为复制构造函数和赋值运算符都不能抛出根据赋值运算符 (a) 实现复制构造函数也很好,并且比在两个地方 (b) 具有几乎相同的代码更易于维护。

关于c++ - 根据复制操作符或单独执行复制操作符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4122014/

相关文章:

c++ - 什么时候调用复制赋值运算符?

c++ - boost multi_index_container 持久化存储在文件中

c# - 可升级和基于插件的应用程序开发

c++ - 传递和分配时保护一些内存

c++ - 为什么 is_copy_assignable 的实现不起作用?

c++ - 动态分配时指向免费商店的新地址是一种好习惯吗?

c++ - 复制构造函数中的递归调用

python - Boost.Python.ArgumentError:World.set(World, str) 中的 Python 参数类型与 C++ 签名不匹配:set(World {lvalue}, std::string)

c++ - 跨平台 C++ 代码和单个 header - 多种实现

c++ - 我们什么时候应该将赋值运算符设为私有(private)而不是实现