interface and opEquals

Steven Schveighoffer schveiguy at yahoo.com
Mon Nov 5 12:33:18 PST 2007


"Oliver" wrote
> Hi everyone,
>
> the following code works and does what it is supposed to do. I am, 
> however, unsure if this is the "right" way to do it. I read somewhere that 
> opEquals should take an Object as argument. I can not get the code to work 
> with Object as argument. Can anyone explain this to be, what am i missing? 
> Thanks to everyone,
>
> Oliver
>
> ------------------------
>
> import std.stdio;
>
> interface Vi {
>    void f();
>    int opEquals( Vi );
>    //int opEquals( Object );
>    //int opEquals();
> }
>
> class C1 : Vi {
>    void f() { writefln( "C1: ", itsInt ); }
>    this( int i ) { this.itsInt = i; }
>    int opEquals( Vi o ) {
>        C1 test = cast(C1)o;
>        return test && this.itsInt == test.itsInt;
>    }
>    //int opEquals( C1 test ) { return this.itsInt == test.itsInt; }
> private:
>    int itsInt;
> }
>
> int main() {
>    assert( 1 == 1.0 );
>    Vi myInt1 = new C1(1);
>    Vi myInt2 = new C1(1);
>    myInt1.f();
>    assert( cast(C1)myInt1 == cast(C1)myInt2 );
>    assert( myInt1 == myInt2 );
>    return 0;
> }
>

You should use Object as the argument.  The reason is simple.  If you do not 
use Object, then the base opEquals function is not overridden.  When you use 
Vi as your argument, you start a new method that is overridden only by 
derivatives of Vi.  Your example isn't a good way to demonstrate why this is 
bad, but imagine if Vi had a base interface...

Having said that, you do not need opEquals to be defined as a method in your 
interface, because Object already defines it.  All classes derived from 
Object will have a valid opEquals.  Perhaps this is why it was not working 
for you.

I think this code would work:

import std.stdio;

interface Vi {
    void f();
    //int opEquals( Vi );  // ** commented out
    //int opEquals( Object );
    //int opEquals();
}

class C1 : Vi {
    void f() { writefln( "C1: ", itsInt ); }
    this( int i ) { this.itsInt = i; }
    int opEquals( Object o ) { // ** changed to Object
        C1 test = cast(C1)o;
        return test && this.itsInt == test.itsInt;
    }
    //int opEquals( C1 test ) { return this.itsInt == test.itsInt; }
private:
    int itsInt;
}

int main() {
    assert( 1 == 1.0 );
    Vi myInt1 = new C1(1);
    Vi myInt2 = new C1(1);
    myInt1.f();
    assert( cast(C1)myInt1 == cast(C1)myInt2 );
    assert( myInt1 == myInt2 );
    return 0;
}

-Steve 




More information about the Digitalmars-d-learn mailing list