【问题标题】:avoiding duplication in the assignment operator of a derived class避免派生类的赋值运算符中的重复
【发布时间】:2015-08-29 02:15:53
【问题描述】:

考虑下面ParentChild 类中的赋值运算符。

#include <iostream>
class Parent 
{
public:
  Parent(){};
  virtual ~Parent(){};
  Parent& operator=(const Parent& other){mP = other.mP; return *this;};

  void setP(double inP){mP = inP;};
  double getP(){return mP;};
protected:
  double mP;
};


class Child : public virtual Parent
{
public:
  Child(){};
  virtual ~Child(){};
  Child& operator=(const Child& other)
  {
     mC = other.mC;
     mP = other.mP;// this line
     return *this;
  };

  void setC(double inC){mC = inC;};
  double getC(){return mC;};
protected:
  double mC;
};

这里有避免重复行mP = other.mP; 的方法吗?

我问的原因是随着基数越来越多,继承结构越来越复杂,很容易忘记成员。

编辑

我需要实现operator=的原因是它需要在分配之前检查一些事情。

【问题讨论】:

  • Parent::operator=(other); 与任何其他方法相同。
  • 我认为您坚持单独分配成员。不要忘记return *this;
  • 在您的情况下,最简单的方法是根本不重载赋值运算符,让编译器默默地为您完成这项工作。
  • @101010 或者换句话说:更喜欢 0 规则而不是 3 规则。

标签: c++ class assignment-operator


【解决方案1】:

避免此问题的最佳方法是删除您的两个 operator= 函数。

编译器生成的operator=operator= 应用于每个成员变量和基类,这正是您想要做的。

重新实现轮子只会使您的代码更难阅读和维护——有时效率会降低。

【讨论】:

  • 如果我有一个const 成员怎么办?那样就不行了,不是吗?
  • @Furihr 如果你有一个非静态的 const 成员,你必须编写所有自己的特殊成员函数;但是分配一个具有这样成员的对象并没有多大意义。我不知道它的任何用例。
  • 想象一个有限差分方案。在许多情况下,推导顺序可能是恒定的。
  • 你不会为此使用 const 成员变量
  • 为什么不呢?在许多情况下它必须是恒定的。由于每个差分方案都必须具有派生顺序,因此我们将其定义为它们公共抽象基类的成员。而且它不能是static consexpr,因为它是在运行时或在每个类中定义的。
【解决方案2】:
Child& operator=(const Child& other)   {
     mC = other.mC;
     mP = other.mP; 
}

您可以通过这种方式在子特定赋值之前调用父赋值运算符:

 Child& operator=(const Child& other)
  {
     Parent::operator=(other);
     mC = other.mC;
     return *this;
  };

【讨论】:

    【解决方案3】:

    只需调用 Parent 运算符:

    Child& operator=(const Child& other)
    {
         mC = other.mC;
         Parent::operator=(other);
         return *this;
    }
    

    或者说真的,不要实现任何一个运算符,因为它们都很简单!

    【讨论】:

    • @AndyG 没有理由进行自我分配检查,不要相信迈耶斯所说的一切。
    • 是的,我想这是偏好。更喜欢保护那些在未来接触我的代码的人。
    • @AndyG 这不是偏好,恕我直言,这很愚蠢。您针对最坏的情况优化代码。
    • @101010:起初你对它“愚蠢”的评论让我有点困扰。然后我决定用谷歌搜索更多关于这个问题的讨论。在阅读了有关自我分配的文献后,我收回了我之前的评论。但是我不认为这一定是“愚蠢的”,但可能是出于对我的程序员同事的不信任感,以便知道如何/何时在将来修改类时处理自我分配。因此,感谢您推动我在这件事上得到更好的教育。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 2019-05-24
    • 2021-07-31
    • 2020-02-16
    • 2012-02-12
    相关资源
    最近更新 更多