[help]operator overloading with opEquals in a class
Jonathan M Davis
jmdavisProg at gmx.com
Wed Nov 3 11:37:14 PDT 2010
On Wednesday, November 03, 2010 10:57:09 Benjamin Thaut wrote:
> Am 03.11.2010 13:07, schrieb zhang:
> > This code belown can be compiled with DMD 2.050. However, it throws an
> > error message: core.exception.HiddenFuncError: Hidden method called for
> > main.AClass
> >
> > I'm not sure about whether it is a bug. Thanks for any help.
> >
> >
> >
> > import std.stdio;
> >
> > class AClass
> > {
> >
> > int data;
> >
> > // It's wrong
> >
> > bool opEquals(AClass a)
> > {
> >
> > writefln("running here.");
> > return data == a.data;
> >
> > }
> >
> > // It works
> > // bool opEquals(Object a)
> > // {
> > // writefln("running here.");
> > // return data == (cast(AClass)a).data;
> > // }
> >
> > }
> >
> >
> > int main(string[] args)
> > {
> >
> > AClass class1 = new AClass();
> > AClass class2 = new AClass();
> >
> > if(class1 == class2)
> >
> > writefln("==");
> >
> > else
> >
> > writefln("!=");
> >
> > return 0;
> >
> > }
> >
> > ----------
> > Zhang<bitworld at qq.com>
> >
> > s
>
> I'm not shure if it is a bug or not, but to fix it you could add "alias
> object.opEquals opEquals;" before your first opEquals. Had that already
> many times, it also happens a lot with opCmp.
It has to do with function overload sets:
http://www.digitalmars.com/d/2.0/function.html
Functions in base classes are completely shadowed by those in the derived class
as far as overloading goes. Using the alias brings the overload into the
overload set for the derived class.
However, I would advise against declaring a version of opEquals() or opCmp()
that takes anything other than an Object. The way they both work is designed
around there being the one overload with takes Object, and generally speaking
having function overloads which take a base and derived class is asking for
trouble. As soon as you add another derived class on top of it, it's going to
choke because it can no longer get an exact match. e.g.
void func(A a) {...}
void func(B b) {...}
class A { ... }
class B : A { ... }
class C : B { ... }
You can't call func with an object of type C without a cast because both the A
and B version accept it and neither match C exactly. D's overloading rules are
stricter than C++'s, which makes it so that you have a lot fewer cases (possibly
none) of a particular overload being called when you expect a different one to be
called, but it also makes it so that the compiler doesn't do some of the
implicit conversions that you might expect it to.
Really, you should just define the one opEquals() and opCmp() and cast the Object
inside of it.h If you'll notice, opEquals() already isn't the function that gets
called when == or != is used, but rather Objects opEquals() which takes two
parameters is, so it already takes care of any issues with the two objects being
the same or being null, as well as dealing with transivity and whatnot. opCmp()
doesn't do that though, so you could likely still get null values in it.
In any case, the design is that you directly override the opEquals() and opCmp()
in Object, not that you create ones with new signatures.
- Jonathan M Davis
- Jonathan M Davis
More information about the Digitalmars-d
mailing list