digitalmars.D.learn - How do you overload opEquals?
- Dale Matthews (32/32) Nov 19 2013 I'm brand new to D and I'm taking on a project. In the midst,
- Adam D. Ruppe (5/6) Nov 19 2013 opEquals doesn't work on classes with class references. It
- Adam D. Ruppe (4/5) Nov 19 2013 IGNORE ME, I am wrong here. I mixed up opEquals and opAssign in
- Dale Matthews (2/5) Nov 19 2013 Will do :]
- Chris Nicholson-Sauls (9/41) Nov 19 2013 override bool opEquals (Object o) const {
- Dale Matthews (7/16) Nov 19 2013 Very cool, it works great! Thanks for the help, Chris.
- Adam D. Ruppe (5/6) Nov 19 2013 Yes, I would use a struct instead of a class here. The key
- Andrea Fontana (10/17) Nov 19 2013 And, of course, struct are value type, class are reference type.
- Adam D. Ruppe (12/13) Nov 19 2013 Yeah, true in general, though it is possible to have a struct be
- Mike Parker (5/8) Nov 19 2013 You don't need to use 'ref' on parameters that are classes. Unlike C++,
I'm brand new to D and I'm taking on a project. In the midst, I've overloaded a whole load of operators for my Vec3 class. Most seem to be working (I haven't tested them all yet) but opEquals is refusing to be called. I've followed the guidelines here: http://dlang.org/operatoroverloading.html#equals class Vec3 { public: float x, y, z; this(float xVal, float yVal, float zVal) { x = xVal, y = yVal, z = zVal; } bool opEquals()(auto ref const Vec3 v) const { debug writeln("bool opEquals(Vec3) called"); return x == v.x && y == v.y && z == v.z; } }; unittest { Vec3 v = new Vec3(5, 10, 15); Vec3 v2 = new Vec3(5, 10, 15); //if(v.opEquals(v2)) //this works great! if(v == v2) //idk where this goes off to but it returns false writeln("FINALLY"); else writeln("try again?"); } I've tried many variations of auto ref and const (although I'm not sure how the function is different for each variation), and it still doesn't get called. I feel like I'm missing something simple.
Nov 19 2013
On Tuesday, 19 November 2013 at 20:59:31 UTC, Dale Matthews wrote:I feel like I'm missing something simple.opEquals doesn't work on classes with class references. It doesn't call a method with obj = other_obj, it just rebinds the reference. If you want full control over opEquals, it'll have to be a struct instead of class.
Nov 19 2013
On Tuesday, 19 November 2013 at 21:05:23 UTC, Adam D. Ruppe wrote:opEquals doesn't work on classes with class references.IGNORE ME, I am wrong here. I mixed up opEquals and opAssign in my head. Sorry!
Nov 19 2013
On Tuesday, 19 November 2013 at 21:22:27 UTC, Adam D. Ruppe wrote:IGNORE ME, I am wrong here. I mixed up opEquals and opAssign in my head. Sorry!Will do :]
Nov 19 2013
On Tuesday, 19 November 2013 at 20:59:31 UTC, Dale Matthews wrote:I'm brand new to D and I'm taking on a project. In the midst, I've overloaded a whole load of operators for my Vec3 class. Most seem to be working (I haven't tested them all yet) but opEquals is refusing to be called. I've followed the guidelines here: http://dlang.org/operatoroverloading.html#equals class Vec3 { public: float x, y, z; this(float xVal, float yVal, float zVal) { x = xVal, y = yVal, z = zVal; } bool opEquals()(auto ref const Vec3 v) const { debug writeln("bool opEquals(Vec3) called"); return x == v.x && y == v.y && z == v.z; } }; unittest { Vec3 v = new Vec3(5, 10, 15); Vec3 v2 = new Vec3(5, 10, 15); //if(v.opEquals(v2)) //this works great! if(v == v2) //idk where this goes off to but it returns false writeln("FINALLY"); else writeln("try again?"); } I've tried many variations of auto ref and const (although I'm not sure how the function is different for each variation), and it still doesn't get called. I feel like I'm missing something simple.override bool opEquals (Object o) const { if ( auto v = cast( typeof( this ) ) o ) return x == v.x && y == v.y && z == v.z; return false; } You need: 1) 'override' in order to override the base class implementation. 2) 'Object' typed parameter, then cast.
Nov 19 2013
On Tuesday, 19 November 2013 at 21:10:57 UTC, Chris Nicholson-Sauls wrote:override bool opEquals (Object o) const { if ( auto v = cast( typeof( this ) ) o ) return x == v.x && y == v.y && z == v.z; return false; } You need: 1) 'override' in order to override the base class implementation. 2) 'Object' typed parameter, then cast.Very cool, it works great! Thanks for the help, Chris. Adam, do you recommend using a struct instead of a class? I'm from C++ where structs are mainly used for PODs. It sounds handy in instances like this though: http://dlang.org/cpptod.html#structcmp
Nov 19 2013
On Tuesday, 19 November 2013 at 21:25:47 UTC, Dale Matthews wrote:Adam, do you recommend using a struct instead of a class?Yes, I would use a struct instead of a class here. The key question to ask in D is: do you need inheritance? If yes, use a class, if no, struct is usually better, since it is lighter weight and generally more flexible.
Nov 19 2013
On Tuesday, 19 November 2013 at 21:33:31 UTC, Adam D. Ruppe wrote:On Tuesday, 19 November 2013 at 21:25:47 UTC, Dale Matthews wrote:And, of course, struct are value type, class are reference type. So, for example: int i = 0; while(++i < 10000000) { S a; // if S is a class S a = new S; a.i = 10; } it's really faster if S is a structAdam, do you recommend using a struct instead of a class?Yes, I would use a struct instead of a class here. The key question to ask in D is: do you need inheritance? If yes, use a class, if no, struct is usually better, since it is lighter weight and generally more flexible.
Nov 19 2013
On Tuesday, 19 November 2013 at 23:58:20 UTC, Andrea Fontana wrote:And, of course, struct are value type, class are reference type.Yeah, true in general, though it is possible to have a struct be very similar to a reference type. Consider: struct WrappedClass { Object obj; /* and whatever other methods, but no more data */ } It's still a value type, but the only member is a reference, so you can use it the same way as any other reference type; it works the same way as Object itself. So struct is flexible in the value vs reference type regard too.
Nov 19 2013
On 11/20/2013 5:59 AM, Dale Matthews wrote:class Vec3 { bool opEquals()(auto ref const Vec3 v) constYou don't need to use 'ref' on parameters that are classes. Unlike C++, D classes are already reference types, not value types. More like Java. Structs, OTOH, are value types. With those, a const ref parameter makes sense, but not with classes.
Nov 19 2013