抽象类和运算符!=在c ++中

Ale*_*zzi 6 c++

我在实现运算符时遇到问题!=在一个派生类中派生出一个抽象的类.代码如下所示:

class Abstract
{
  public:
     //to make the syntax easier let's use a raw pointer
     virtual bool operator!=(const Abstract* other) = 0;
};

class Implementation
{
    SomeObject impl_; //that already implement the operator!=
  public:
    bool operator!=(const Abstract* other)
    {
      return dynamic_cast<Implementation*>(other)->impl_ != this->impl_;
    }
};
Run Code Online (Sandbox Code Playgroud)

这段代码有效,但它有使用dynamic_cast的缺点,我需要处理转换操作中的错误.

这是一个泛型问题,当它试图使用某些内部信息(在抽象类级别不可用)执行任务的具体类的函数时发生.

有没有更好的方法来解决这类问题?

干杯

Tho*_*ews 5

你不想实现平等的运营商,==或者!=,在一个基类.基类不知道后代的数量或内容.

例如,使用Shape类示例:

struct Shape
{
  virtual bool equal_to(const Shape& s) const = 0;  // Makes Shape an abstract base class.
  bool operator==(const Shape& s) const
  {
     return equal_to(s);
  }
  bool operator!=(const Shape& s) const
  {
     return !equal_to(s);
  }
};

struct Square : public Shape
{
  bool equal_to(const Shape& s) const;
};

struct Circle : public Shape
{
  bool equal_to(const Shape& s) const;
};

struct Flower : public Shape
{
  bool equal_to(const Shape& s) const;
};

struct Cloud : public Shape
{
  bool equal_to(const Shape& s) const;
};
Run Code Online (Sandbox Code Playgroud)

为了满足Shape类的相等运算符,每个后代都必须实现该equal_to方法. 但是等等,怎么Square知道对方Shape是什么类型的?

在此示例中,Square类需要dynamic_cast在引用上使用强制转换为Square对象.当参数是这将失败Circle,Flower,Cloud或一些其他尚未确定的形状.

以下是您必须注意的有效概念:

Square my_square;
Cloud  my_cloud;
Shape * p_shape_1 = &my_square;  // Square is-a Shape, so this is legal.
Shape * p_shape_2 = &my_cloud;   // Cloud inherits from Shape, so this is legal.

if (*p_shape_1 == *p_shape_2)  // Legal syntax because of Shape::operator==().
{ //???}
Run Code Online (Sandbox Code Playgroud)

上面的比较调用了讨厌的行为.这可以在仅在形状上操作的通用函数中实现.

解析度

改变设计.您永远不应该在基类中放置一个与基类相比较的公共比较运算符.讨厌.

后代与后代相比.期. 正方形到正方形,花到花和圆到圆形.在后代类中实现比较运算符.

比较基类内容: 如果您在基类中有共享内容,请实现受保护的方法以仅比较基类方法:

struct Shape
{
  protected:
    bool equal_shape_content(const Shape& s) const;
};
Run Code Online (Sandbox Code Playgroud)

这将使您的程序更加健壮,因为它只将Shape的内容与另一个Shape进行比较.这是你可以保证的一切.另请参见基类切片.