Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
March 22, 2006 opEquals footprint | ||||
---|---|---|---|---|
| ||||
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 |
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to Erik Rasmussen | 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
|
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | 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
|
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to Erik Rasmussen | 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
|
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to Erik Rasmussen | 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
|
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | 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
|
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | 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;
}
}
|
March 22, 2006 Re: opEquals footprint | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | 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; } > } |
Copyright © 1999-2021 by the D Language Foundation