www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opEquals footprint

reply Erik Rasmussen <i_am_erik yahoo.com> writes:
I've looked all around in the documentation and forum discussions, and I 
can't find the answer to this simple, but all-important question:

***** What should the type of the parameter to opEquals be??? *****

I can see two possibilities:

A) Object.  This would force you to check the type of the object passed 
in as part of your equivalence check.  Could this perhaps be done at 
compile-time with an is() expression?

B) The same type as the class.  This is fine, but I don't think 
subclasses properly override the superclass's opEquals implementations 
when this is the case.

Can someone settle this?  What is the proper way to implement opEquals??

Thanks,
Erik
Mar 22 2006
parent reply xs0 <xs0 xs0.com> writes:
Erik Rasmussen wrote:
 I've looked all around in the documentation and forum discussions, and I 
 can't find the answer to this simple, but all-important question:
 
 ***** What should the type of the parameter to opEquals be??? *****
 
 I can see two possibilities:
 
 A) Object.  This would force you to check the type of the object passed 
 in as part of your equivalence check.  Could this perhaps be done at 
 compile-time with an is() expression?
 
 B) The same type as the class.  This is fine, but I don't think 
 subclasses properly override the superclass's opEquals implementations 
 when this is the case.
 
 Can someone settle this?  What is the proper way to implement opEquals??
 
 Thanks,
 Erik

int opEquals(Object) so it overrides the default implementation found in, you guessed it, Object :) Same goes for opCmp, I think.. xs0
Mar 22 2006
next sibling parent reply Erik Rasmussen <i_am_erik yahoo.com> writes:
xs0 wrote:
 int opEquals(Object)
 
 so it overrides the default implementation found in, you guessed it, 
 Object :) Same goes for opCmp, I think..
 
 
 xs0

So what's the best way to actually check the type in the opEquals/opCmp method? Something like... class A { int opEquals(Object o) { // check for null if(o is null) return false; // check type if(typeid(typeof(o)) != typeid(A)) return false; // cast A that = cast(A) o; // actually check fields return this.a == that.a && this.b == that.b && ...; } } Or is there a better way? asserts? How do you hard-core D programmers usually do it? Cheers, Erik
Mar 22 2006
next sibling parent reply xs0 <xs0 xs0.com> writes:
Erik Rasmussen wrote:
 xs0 wrote:
 int opEquals(Object)

 so it overrides the default implementation found in, you guessed it, 
 Object :) Same goes for opCmp, I think..


 xs0

So what's the best way to actually check the type in the opEquals/opCmp method? Something like... class A { int opEquals(Object o) { // check for null if(o is null) return false; // check type if(typeid(typeof(o)) != typeid(A)) return false; // cast A that = cast(A) o; // actually check fields return this.a == that.a && this.b == that.b && ...; } } Or is there a better way? asserts? How do you hard-core D programmers usually do it? Cheers, Erik

Something like this should be ok: // optional if (this is o) return true; if (A that = cast(A)o) { // checks for null, too return this.a==that.a && ... } else { return false; } OTOH, if you want to return false for subclasses, your version seems fine to me. xs0
Mar 22 2006
parent Erik Rasmussen <i_am_erik yahoo.com> writes:
xs0 wrote:
 Erik Rasmussen wrote:
 
 xs0 wrote:

 int opEquals(Object)

 so it overrides the default implementation found in, you guessed it, 
 Object :) Same goes for opCmp, I think..


 xs0

So what's the best way to actually check the type in the opEquals/opCmp method? Something like... class A { int opEquals(Object o) { // check for null if(o is null) return false; // check type if(typeid(typeof(o)) != typeid(A)) return false; // cast A that = cast(A) o; // actually check fields return this.a == that.a && this.b == that.b && ...; } } Or is there a better way? asserts? How do you hard-core D programmers usually do it? Cheers, Erik

Something like this should be ok: // optional if (this is o) return true; if (A that = cast(A)o) { // checks for null, too return this.a==that.a && ... } else { return false; } OTOH, if you want to return false for subclasses, your version seems fine to me. xs0

No, I definitely don't want it to return false for subclasses! That "failed cast returns null" trick is handy. That's waaay better than all that typeid(typeof()) crap. Thanks guys. Erik
Mar 22 2006
prev sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
class A
{
	int opEquals(Object o)
	{
		A a = cast(A) o;

		if (a is null)
			return false;
		else
			return this.member1 == a.member1;
	}
}

Casting will return null if it fails, so to speak (so you definitely 
need to check after it for null.)  Typeof will always give "Object" for 
o since that's its compile-time type.

-[Unknown]


 xs0 wrote:
 int opEquals(Object)

 so it overrides the default implementation found in, you guessed it, 
 Object :) Same goes for opCmp, I think..


 xs0

So what's the best way to actually check the type in the opEquals/opCmp method? Something like... class A { int opEquals(Object o) { // check for null if(o is null) return false; // check type if(typeid(typeof(o)) != typeid(A)) return false; // cast A that = cast(A) o; // actually check fields return this.a == that.a && this.b == that.b && ...; } } Or is there a better way? asserts? How do you hard-core D programmers usually do it? Cheers, Erik

Mar 22 2006
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
xs0 wrote:
 
 int opEquals(Object)
 
 so it overrides the default implementation found in, you guessed it, 
 Object :) Same goes for opCmp, I think..

It's probably worth also supplying overloads for the class in question, as you don't want to cast if you don't have to: class A { int opEquals(Object o) { A a = cast(A) o; if (a is null) return false; else return *this == a; } }
Mar 22 2006
parent Sean Kelly <sean f4.ca> writes:
Forgot the second overload.


Sean Kelly wrote:
 xs0 wrote:
 int opEquals(Object)

 so it overrides the default implementation found in, you guessed it, 
 Object :) Same goes for opCmp, I think..

It's probably worth also supplying overloads for the class in question, as you don't want to cast if you don't have to: class A { int opEquals(Object o) { A a = cast(A) o; if (a is null) return false; else return *this == a; }

int opEquals( A a ) { return member1 == a.member1; }
 }

Mar 22 2006