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