【问题标题】:"Almost default" copy constructor (& assignment operator) in C++C ++中的“几乎默认”复制构造函数(和赋值运算符)
【发布时间】:2014-07-11 23:38:13
【问题描述】:

我发现自己做的一件常见事情是制作“几乎默认”的复制构造函数和赋值运算符。也就是说,我发现自己处于编译器提供的复制和赋值运算符适用于大多数数据成员的情况,但是有一个特定的数据成员需要以不同的方式处理。这意味着我必须显式创建一个复制构造函数/赋值运算符,包括显式列出所有具有简单复制语义的数据成员。对于有相当数量的数据成员的类,或者稍后添加成员变量但未添加到复制构造函数/赋值运算符时,这可能会很烦人。

有没有办法告诉 C++ 编译器显式声明的复制构造函数/赋值运算符应该像隐式一样工作,除了一些随后运行的附加代码? (而且这样的语法是C++98兼容吗,还是需要C++11或者C++14支持?)

【问题讨论】:

  • 为该数据成员实施适当的 RAII 包装器,然后默认构造函数将适用于所有内容。

标签: c++ copy-constructor assignment-operator


【解决方案1】:

如果您可以按照 Igor Tandetnik 的建议将特定处理隔离在适当的 RAII 包装器中:那就去吧。

如果您仍然需要在复制构造函数和/或赋值运算符中进行特定处理(例如在容器或日志中注册对象创建/赋值),您可以将可以默认复制构造/赋值的数据成员分组到一个您用作基类或数据成员的单独类,您将其作为复合处理,因此:

struct x_base {
  int a,b,c,d;
  std::string name;
};

struct x : x_base {
     x(const x& other)
         : x_base(other) 
     {
         descr = "copied ";
         descr += name;
         descr += " at ";
         descr += CurrentTimeAsString();
         std::cout << descr << "\n";
     }
     void operator = (const x& other)
     {
         x_base::operator =(other); 
         descr = "assigned ";
         descr += name;
         descr += " at ";
         descr += CurrentTimeAsString();
         std::cout << descr << "\n";
     }
     std::string descr;
};

当您稍后添加不需要特定处理的数据成员时,您可以简单地将它们添加到 x_base。

【讨论】:

  • 这利用了为非联合类隐式定义的复制构造函数执行其基类和成员的成员复制的原则(标准 C++,第 12.8 节第 15 节)。但是请注意,这对成员副本的完成顺序有一些限制。
猜你喜欢
  • 1970-01-01
  • 2013-03-16
  • 2020-06-13
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 2013-09-28
  • 2011-06-09
相关资源
最近更新 更多