If you don't care about comparisons of type A to type B, or B to C, etc. then you can simply implement an overloaded equality operator for each class:
class A {
public: int data;
bool operator==(const A& rhs) {
return (data == rhs.data);
}
};
class B : public A {
public: float more_data; bool something_else;
bool operator==(const B& rhs) {
return (A::operator==( data ) &&
more_data == rhs.more_data &&
something_else == rhs.something_else);
}
};
That's dangerous though, because if you derive a new class D from B or C, you're going to have problems.
Otherwise you need to implement some comparators with a lot of dynamic_cast<>-ing to really do it right. Alternatively you could implement a function to create a hash code for each object and leverage that, e.g.
class A {
public: int data;
virtual long getHashCode() const {
// compute something here for object type A
}
// virtual here just in case you need to overload it in B or C
virtual bool equals( const A& obj ) const {
return (typeid(*this) == typeid(obj) &&
getHashCode() == obj->getHashCode());
}
};
class B : public A {
public: float more_data; bool something_else;
virtual long getHashCode() const {
// compute something here for object type B
}
};
class C : public A {
public: double more_data;
virtual long getHashCode() const {
// compute something here for object type C
}
};
If you incorporate the object's type into the hash code in some fashion (not shown above) then you can also dispense with the silly typeid() comparisons above.