如何查看两个多态对象是否相等?例如
struct A {};
struct A1 : public A
{
int i;
bool operator==(A1 const& other) const { return i == other.i; }
};
struct A2 : public A
{
float f;
bool operator==(A2 const& other) const { return f == other.f; }
};
bool isEqual(A const& x, A const& y)
{
if (typeid(x) != typeid(y))
return false;
... // Then how to compare when they have same type. Any way to cast them
// to their dynamic types by typeid or others
}
答案 0 :(得分:2)
我使用“奇怪的重复模板”模式,但在基类和派生类之间有一个辅助类。
首先,在基类operator==
中添加纯虚拟A
。
编写一个帮助程序类,负责将比较重定向到动态类型类。这个帮助器类有两个模板类型参数:基类和具体类;这个类应该来自基类:
template<typename Base, typename Derived>
struct PolymorphicComparable : public Base {
...
};
在此课程中,您实施operator==
(如果Base==A
以后,这将是一个覆盖):
bool operator==(const Base &other) const {
// first check if the dynamic types match
if (typeid(other) != typeid(Derived))
return false;
// cast to the concrete types; thanks to the check above this is safe
const Derived & a = static_cast<const Derived&>(*this);
const Derived & b = static_cast<const Derived&>(other);
// redirect to Derived::operator==(Derived)
return a == b;
}
现在,A
的子类不直接子类A
,而是上面的类(这是“奇怪的重复模板”),并且每个都实现了自己的operator==
而没有需要额外的代码:
struct A1 : public PolymorphicComparable<A,A1>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
int i;
bool operator==(const A1 &other) const {
return i == other.i;
}
};
注意:帮助程序类模板只需一次,不仅每个基类一次,而且在整个代码库中只需一次,即使您有多个基类要根据多态类型。
答案 1 :(得分:1)
在A
函数中为operator==
函数创建虚拟成员函数。使用operator!=
实施operator==
。
struct A
{
virtual bool operator==(A const& other) const = 0;
bool operator!=(A const& other) const
{
return !(*this == other);
}
};
在具体类中实现operator==
函数并添加必要的检查。
struct A1 : public A
{
int i;
virtual bool operator==(A const& other) const
{
// Do dynamic cast to make sure that other is of type A1.
A1 const* otherPtr = dynamic_cast<A1 const*>(&other);
if ( otherPtr == NULL )
{
return false;
}
else
{
return i == otherPtr->i;
}
}
};
<强>更新强>
如果A
在比较两个对象时需要考虑数据......
struct A
{
virtual bool operator==(A const& other) const
{
return (j == other.j);
}
bool operator!=(A const& other) const
{
return !(*this == other);
}
int j;
};
struct A1 : public A
{
int i;
virtual bool operator==(A const& other) const
{
if ( !(A::operator==(other)) )
{
return false;
}
// Do dynamic cast to make sure that other is of type A1.
A1 const* otherPtr = dynamic_cast<A1 const*>(&other);
if ( otherPtr == NULL )
{
return false;
}
else
{
return i == otherPtr->i;
}
}
};