C++ 避免派生类的赋值运算符重复

C++ 避免派生类的赋值运算符重复,c++,class,assignment-operator,C++,Class,Assignment Operator,考虑下面类父类和子类中的赋值运算符 #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;};

考虑下面类
父类
子类
中的赋值运算符

#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;
};
#包括
班级家长
{
公众:
父(){};
虚拟~Parent(){};
父操作符=(const Parent&other){mP=other.mP;返回*this;};
void setP(双inP){mP=inP;};
double getP(){return mP;};
受保护的:
双mP;
};
类子级:公共虚拟父级
{
公众:
Child(){};
虚拟~Child(){};
子运算符和运算符=(常量子运算符和其他运算符)
{
mC=其他.mC;
mP=other.mP;//此行
归还*这个;
};
void setC(double inC){mC=inC;};
double getC(){return mC;};
受保护的:
双mC;
};
这是一种避免重复行
mP=other.mP的方法

我提出这个问题的原因是,随着碱基的数量越来越高,继承结构越来越复杂,很容易失去对成员的跟踪

编辑


我需要实现
操作符=
的原因是它需要在赋值之前检查一些事情。

只需调用父操作符:

Child& operator=(const Child& other)
{
     mC = other.mC;
     Parent::operator=(other);
     return *this;
}
或者实际上,不要实现任何一个操作符,因为这两个操作符都是微不足道的

Child& operator=(const Child& other)   {
     mC = other.mC;
     mP = other.mP; 
}
您可以通过以下方式在特定于子项的赋值之前调用父项的赋值运算符:

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

避免此问题的最佳方法是删除两个
运算符=
函数

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


重新实现控制盘只会使代码更难阅读和维护,有时效率更低。

Parent::operator=(其他)与任何其他方法相同。我认为您必须单独分配成员。不要忘记
返回*this在您的情况下,最简单的方法是根本不重载赋值运算符,让编译器默默地为您完成任务。@101010或者换句话说:更喜欢0规则而不是3规则。@AndyG没有理由进行自赋值检查,不要相信Meyers说的一切。是的,我想这是首选。更愿意保护那些在将来接触我的代码的人不受他们自己的影响。@AndyG这不是一种偏好,我觉得这很愚蠢。你在最坏的情况下优化了你的代码。@101010:起初,你关于它“愚蠢”的评论让我有点不安。然后我决定在谷歌上搜索更多关于这个问题的讨论。在阅读了有关自我分配的文献之后,我收回了我先前的评论。然而,我并不认为这一定是“愚蠢的”,也许是因为我的程序员同事不信任我,不知道如何/何时在将来修改类时处理自我分配。所以,谢谢你促使我在这方面接受更好的教育。如果我有一个
const
成员怎么办?如果你有一个非静态的const成员,你就必须编写自己所有的特殊成员函数;但是,指定一个具有这样一个成员的对象没有多大意义。我不知道它的任何用例。想象一下一个有限差分方案。在许多情况下,派生的顺序可以是常量。你不会为此使用常量成员变量,为什么不呢?在许多情况下,它必须是常数。由于每个差分方案都必须有一个派生顺序,因此我们将其定义为其公共抽象基类的一个成员。而且它不能是静态conexpr,因为它是在运行时或在每个类中定义的。