Equality Test for Derived Classes in C++

c++, equality, equals-operator, inheritance, operators

Solution

I remember reading a succinct description of the public-non-virtual/non-public-virtual idiom and its advantages, but not where. This wikibook has an okay description.

Here is how you apply it to op==:

struct A {
  virtual ~A() {}

  int a;

  friend
  bool operator==(A const& lhs, A const& rhs) {
    return lhs.equal_to(rhs);
  }
  // http://en.wikipedia.org/wiki/Barton-Nackman_trick
  // used in a simplified form here

protected:
  virtual bool equal_to(A const& other) const {
    return a == other.a;
  }
};

struct B : A {
  int b;

protected:
  virtual bool equal_to(A const& other) const {
    if (B const* p = dynamic_cast<B const*>(&other)) {
      return A::equal_to(other) && b == p->b;
    }
    else {
      return false;
    }
  }
};

struct C : A {
  int c;

protected:
  virtual bool equal_to(A const& other) const {
    if (C const* p = dynamic_cast<C const*>(&other)) {
      return A::equal_to(other) && c == p->c;
    }
    else {
      return false;
    }
  }
};

Problem

Possible Duplicate: What’s the right way to overload operator== for a class hierarchy? In C++, how can derived classes override the base class equality test in a meaningful way? For example, say I have a base class A. Classes B and C derive from A. Now given two pointers to two A objects, can I test if they are equal (including any subclass data)? ``` class A { public: int data; }; class B : public A { public: float more_data; bool something_else; }; class C : public A { public: double more_data; }; A* one = new B; A* two = new B; A* three = new C; //How can I test if one, two, or three are equal //including any derived class data? ``` Is there a clean way of doing it? What's my best bet? Thanks!

Original source

Related problems