TITLE: virtual operator == PROBLEM: "Phil Verghese" I'm trying to implement a virtual operator==, and I'd like to avoid having to use RTTI in the derived classes. RESPONSE: rmartin@oma.com (Robert C. Martin), 25 Jan 96 If you need to avoid RTTI because your compiler doesn't support it, then I have no objection. But if you are avoiding RTTI because you think it is evil, then I suggest you modify your outlook. RTTI is not inherently evil, although the potential for abuse is high. Still, implementing operator== with RTTI (i.e. dynamnic_cast) is not one of those abuses. If your compiler does not support RTTI, there are some simple ways to simulate it; which I will explore below. PV: My code looks like this: #include class Base { public: Base(int data) : fData(data) {} virtual int operator==(const Base& x) const { return fData == x.fData; } protected: int fData; }; class Derived : public Base { public: Derived(float data) : fDerData(data), Base(0) {} virtual int operator==(const Base& x) const { // First, compare base data members int ret=(Base::operator==(x)); // Now compare derived data members if (ret==1) { //------------------------------------ // Need to do a downcast here, I think //------------------------------------ // downcast to Derived, and compare // fDerData members // if downcast fails, return false? RM: ========================================================== Right. With RTTI this looks like the following: Derived* d = dynamic_cast(&x); if (d) { // compare } else ret=0; ========================================================= PV: } return (ret); } protected: float fDerData; }; Is there any way to implement this while without using RTTI? RM: Sure. You can use the visitor pattern from "Design Patterns", Addison Wesley, Gamma, et. al. There is a good example of how to use this pattern in chapter 4 of my book: Designing Object Oriented C++ Applications using the Booch Method, Robert Martin, Prentice Hall, 1995 ISBN 0-13-203837-4 class Visitor; class Base { public: virtual void Visit(Visitor&) = 0; }; class Derived1; class Derived2; class Visitor { public: virtual void Visit(Derived1*) = 0; virtual void Visit(Derived2*) = 0; }; class Derived1 : public Base; { public: virtual void Visit(Visitor& v) {v.Visit(this);} }; class Derived2 : public Base; { public: virtual void Visit(Visitor& v) {v.Visit(this);} }; class RTTIVisitor : public Visitor { public: RTTIVisitor() : itsD1(0), itsD2(0) {} virtual void Visit(Derived1* d1) {itsD1 = d1;} virtual void Visit(Derived2* d2) {itsD2 = d2;} Derived1* GetD1() {return itsD1;} Derived2* GetD2() {return itsD2;} private: Derived1* itsD1; Derived2* itsD2; }; Derived1* dynamic_cast_Derived1(Base* b) { RTTIVisitor v; b.Visit(v); return v.GetD1(); } Derived2* dynamic_cast_Derived2(Base* b) { RTTIVisitor v; b.Visit(v); return v.GetD2(); } So, now you can implement your operator== as: bool Derived1::operator==(const Base& b) { bool ret = true; Derived1* d1 = dynamic_cast_Derived1(&b); if (d1) // compare else ret = false; return ret; };