如何在c ++中实现operator == for polymorphic classes

时间:2012-10-24 08:25:34

标签: c++

  

可能重复:
  What’s the right way to overload operator== for a class hierarchy?

我有一个基类和几个派生类,如下面的代码所示:

class Base
{
public:
    friend bool operator==(const Base&, const Base&);
    virtual ~Base(){}

private:
    virtual bool equals(const Base& other) const = 0;
};

bool operator==(const Base& lhs, const Base& rhs)
{
    return lhs.equals(rhs);
}

class A : public Base
{
public:
    A(int x) : x_(x){}

private:
    virtual bool equals(const Base& other) const;
    int x_;
};

bool A::equals(const Base& other) const
{
    const A* pA = dynamic_cast<const A*>(&other);
    if(!pA) return false;
    return x_ == pA->x_;
}

class B : public Base
{
public:
    B(double y) : y_(y){}

private:
    virtual bool equals(const Base& other) const;
    double y_;
};

bool B::equals(const Base& other) const
{
    const B* pB = dynamic_cast<const B*>(&other);
    if(!pB) return false;
    return y_ == pB->y_;
}

为了能够比较我想要拥有operator ==的两个派生类。问题是如何以面向对象的方式实现这一点(例如,尊重封装,可维护性和可扩展性)。是否有一些推荐的模式可以做到这一点?有没有替代上述方法来避免dynamic_cast?

1 个答案:

答案 0 :(得分:3)

你的方式并不完美。考虑从A得到的下一个类:

class AA : public A
{
public:
    AA(int x, int y) : A(x), y_(y) {}

private:
    virtual bool equals(const Base& other) const;
    int y_;
};

bool AA::equals(const Base& other) const
{
    const AA* pAA = dynamic_cast<const AA*>(&other);
    if(!pAA) return false;
    return A::equals(other) && y_ == pAA->y_;
}

那么你的operatator ==打破了基本规则,它不是对称关系:

   A a(1); 
   AA aa(1,1); 
   assert(a == aa);
   assert(!(aa == a));

简短修复是使用typeid

bool operator==(const Base& lhs, const Base& rhs)
{
    return typeid(lhs) == typeid(rhs) && lhs.equals(rhs);
}