Overriding the C++ Operator== 
by Daniel E. Stevenson and Andrew T. Phillips

Listing One

abstract class T {
    public final boolean equals(Object that) {
        boolean isEqual = false;
        if ((that != null) && (that instanceof T)) {
            T castedThat = (T) that;
            if (this.getTypeEquiv().equals(castedThat.getTypeEquiv())) {
                isEqual = blindlyEquals(that);
            }
        }
        return isEqual;
    }
    protected boolean blindlyEquals(Object that) {
        return true; // to stop the chaining
    }
    abstract protected Class getTypeEquiv();
}
class A extends T {
    protected boolean blindlyEquals(Object that) {
        A castedThat = (A) that;
        // perform comparisons on private data
        boolean isEqual = (this.x == castedThat.x);
        return (isEqual && super.blindlyEquals(that));
    }
   protected Class getTypeEquiv() {
        Class result = null;
        try { // will never fail, but must try/catch
            result = Class.forName("A");
        } catch (ClassNotFoundExeception e) { }
        return result;
    }
    private int x;
}


Listing Two
class B extends A {
    protected boolean blindlyEquals(Object that) {
        B castedThat = (B) that;
        // perform comparisons on private data
        boolean isEqual = (this.y == castedThat.y);
        return (isEqual && super.blindlyEquals(that));
    }
    protected Class getTypeEquiv() {
        Class result = null;
        try { // will never fail, but must try/catch
            result = Class.forName("B");
        } catch (ClassNotFoundExeception e) { }
        return result;
    }
    private int y;
}


Listing Three

class T {
public:
    bool operator==(const T &that) const {
        bool isEqual = false;
        if ((&that != NULL) && (*(this->getTypeEquiv()) == *(that.getTypeEquiv()))) {
            isEqual = (this->blindlyEquals(&that));
        }
        return isEqual;
    }
protected:
    virtual bool blindlyEquals(const T *that) const {
        return true; // default to stop the chaining
    }
    virtual const type_info* getTypeEquiv() const = 0;
};
class A : public T {
protected:
    virtual bool blindlyEquals(const T *that) const {
        const A *castedThat = dynamic_cast<const A*>(that);
        // perform comparisons on private data
        bool isEqual = (this->x == castedThat->x);
        return (isEqual && T::blindlyEquals(that));
    }
    virtual const type_info* getTypeEquiv() const {
        return &typeid(*(new A()));
    }
private:
    int x;
};


Listing Four

A *instanceA = new A;
B *instanceB = new B;
if (*instanceB == *instanceA) {
    // which version of == will run??
}


Listing Five

abstract class T { // Java version
 ... // same as before
    protected final Class getTypeEquiv() {
        return this.getClass();
    }
}
class T { // C++ version
. // same as before
protected:
    const type_info* getTypeEquiv() const {
        return &typeid(*this);
    }
}




2


