如何看两个多态对象是否相等?

时间:2014-06-16 17:46:10

标签: c++ polymorphism

如何查看两个多态对象是否相等?例如

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
}

2 个答案:

答案 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;
    }
};

注意:帮助程序类模板只需一次,不仅每个基类一次,而且在整个代码库中只需一次,即使您有多个基类要根据多态类型。

Live Demo

答案 1 :(得分: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);
        }
    };
    
  2. 在具体类中实现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;
           }
        }
    };
    
  3. <强>更新

    如果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;
           }
        }
    };