【问题标题】:c++ copy constructor - implicit copy for all but one field?c++ 复制构造函数 - 除了一个字段之外的所有字段的隐式复制?
【发布时间】:2023-04-02 18:06:01
【问题描述】:

假设我有一个包含许多字段的类,和/或不断变化(在开发中),并且它的所有字段都是本地的或提供令人满意的复制构造函数的非必要 POD 类型,但是一个 - 它甚至可能已删除或私有化其复制构造函数,但为我提供了根据需要进行复制的方法。
现在假设我需要它有自己的复制构造函数。
我是否必须逐个字段地编写详尽的(用尽的)字段,或者是否有一种更清洁、更少暴露于错误的方法来实现相同的目标?

图解代码:

class Big {
public :
  Big(Big const & big) : ? { ? }
protected :
  int i1, i2, ... , i50;
  float f1, f2, ... , f50;
  CopyConstructableClass1 c1;
  CopyConstructableClass2 c2;
  ...
  CopyConstructableClass20 c20;
  NonCopyConstructableClass ncc;
};

谢谢

【问题讨论】:

    标签: c++ copy-constructor


    【解决方案1】:

    您可以将有问题的令人讨厌的类包装到您自己设计的一个可完全复制的类中,然后将您的大型、不断变化的类中的字段设为该包装器类型而不是原始类型。这样,您只需要在一个地方完成一次“自定义复制”的工作,然后您就可以在其他地方重用该逻辑。

    这是遵循单一职责原则,该原则指出每个类都应该有一个职责,而复杂性是由组合构建的。

    【讨论】:

      【解决方案2】:

      通常我在这种情况下所做的是将所有可以复制自己的字段放入基类中。比我可以有一个只有一个字段的派生类,它将被手动复制。

      为了强调这个基类不能单独使用,将它标记为析构函数protected 是谨慎的。其实它的所有成员都可以。

      【讨论】:

      • 我在写下这个问题时考虑过,但感觉就是错的(审美方面)。上面的答案有一个更好的方法。
      • @elad,这取决于你。我讨厌必须在该内部类的所有成员前面加上类名,我认为这是一个有效的继承案例。你可能有不同的审美观点。
      【解决方案3】:

      考虑一些会跳过赋值运算符逻辑的东西。举个例子(不是真实的代码):

      template <typename T>
      class DontCopyThisField : public T
      {
      public:
          template <typename... Args>
          DontCopyThisField(Args&&... args):
              T(std::forward<Args>(args)...)
          {
          }
      
          DontCopyThisField(const DontCopyThisField& from)
          {
          }
      
          DontCopyThisField(DontCopyThisField&& from):
              T(static_cast<T&&>(from))
          {
          }
      
          DontCopyThisField& operator=(const T& from)
          {
              T::operator=(from);
              return *this;
          }
      
          DontCopyThisField& operator=(T&& from)
          {
              T::operator=(std::move(from));
              return *this;
          }
      
          DontCopyThisField& operator=(const DontCopyThisField& from)
          {
              return *this;
          }
      
          DontCopyThisField& operator=(DontCopyThisField&& from)
          {
              T::operator=(static_cast<T&&>(from));
              return *this;
          }
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-24
        • 2017-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-23
        相关资源
        最近更新 更多