可能重复:
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?
答案 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);
}