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<bitwo...@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

Reply via email to