www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to Compare 2 objects of the same class

reply Mark <tigchelaarm mymacewan.ca> writes:
Hello again.

I'm designing a template version of a BST.

Because of this, I want to be able to compare if two objects of 
the same class type are references to the same anonymous class on 
the heap somewhere.

Example:
Jun 03
parent reply Mark <tigchelaarm mymacewan.ca> writes:
On Saturday, 3 June 2017 at 19:57:47 UTC, Mark wrote:
 Hello again.

 I'm designing a template version of a BST.

 Because of this, I want to be able to compare if two objects of 
 the same class type are references to the same anonymous class 
 on the heap somewhere.

 Example:
Not sure what happened there. Anyways, example: auto A = new Box(); auto B = new Box(); if(A.opEquals(B)) {} gives the error test.o:(.data.rel.ro+0x18): undefined reference to `_D5Stack12__ModuleInfoZ' collect2: error: ld returned 1 exit status Error: linker exited with status 1 if(Object.opEquals(A,B) gives test.d(10): Error: function object.Object.opEquals (Object o) is not callable using argument types (Box, Box) How do I got about comparing two objects then?? Thanks.
Jun 03
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 3 June 2017 at 20:02:13 UTC, Mark wrote:
 On Saturday, 3 June 2017 at 19:57:47 UTC, Mark wrote:
 Hello again.

 I'm designing a template version of a BST.

 Because of this, I want to be able to compare if two objects 
 of the same class type are references to the same anonymous 
 class on the heap somewhere.

 Example:
Not sure what happened there. Anyways, example: auto A = new Box(); auto B = new Box(); if(A.opEquals(B)) {} gives the error test.o:(.data.rel.ro+0x18): undefined reference to `_D5Stack12__ModuleInfoZ' collect2: error: ld returned 1 exit status Error: linker exited with status 1 if(Object.opEquals(A,B) gives test.d(10): Error: function object.Object.opEquals (Object o) is not callable using argument types (Box, Box) How do I got about comparing two objects then?? Thanks.
I think that the error is unrelated. Which dmd do you use ? Otherwise, opEquals (or just == ) is well the way to follow. By default Object.opEquals just compare the Objects addresses. If you want to perform a deep comparison (i.e the members) you have to override opEquals.
Jun 03
prev sibling next sibling parent cym13 <cpicard openmailbox.org> writes:
On Saturday, 3 June 2017 at 20:02:13 UTC, Mark wrote:
 On Saturday, 3 June 2017 at 19:57:47 UTC, Mark wrote:
 Hello again.

 I'm designing a template version of a BST.

 Because of this, I want to be able to compare if two objects 
 of the same class type are references to the same anonymous 
 class on the heap somewhere.

 Example:
Not sure what happened there. Anyways, example: auto A = new Box(); auto B = new Box(); if(A.opEquals(B)) {} gives the error test.o:(.data.rel.ro+0x18): undefined reference to `_D5Stack12__ModuleInfoZ' collect2: error: ld returned 1 exit status Error: linker exited with status 1 if(Object.opEquals(A,B) gives test.d(10): Error: function object.Object.opEquals (Object o) is not callable using argument types (Box, Box) How do I got about comparing two objects then?? Thanks.
Could you please systematically post compilable code? It is very hard to say anything without even seeing what you're struggling with.
Jun 03
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 06/03/2017 10:02 PM, Mark wrote:

 auto A = new Box();
 auto B = new Box();
 
 if(A.opEquals(B)) {}
 
 gives the error
 test.o:(.data.rel.ro+0x18): undefined reference to 
 `_D5Stack12__ModuleInfoZ'
 collect2: error: ld returned 1 exit status
 Error: linker exited with status 1
Your code works for me (when adding `class Box {}` and a `main` function). An "undefined reference" error can mean that you forgot to include a module on the command line.
 if(Object.opEquals(A,B) gives
 
 test.d(10): Error: function object.Object.opEquals (Object o) is not 
 callable using argument types (Box, Box)
Yeah, that's not how you do it.
 How do I got about comparing two objects then??
 Thanks.
Just use the usual equality operator: `==`. Or if you want to check for identity, use the binary `is` operator. ---- class Box {} void main() { auto A = new Box(); auto B = new Box(); if (A == B) {} if (A is B) {} } ---- By default, they act the same. But you can change how `==` behaves by overriding `opEquals`. You cannot override `is`.
Jun 03
parent reply Mark <tigchelaarm mymacewan.ca> writes:
On Saturday, 3 June 2017 at 20:24:44 UTC, ag0aep6g wrote:

 By default, they act the same. But you can change how `==` 
 behaves by overriding `opEquals`. You cannot override `is`.
Ok. So by using '==' it should compare the addresses of the objects? I think I didn't include the other file as an argument on the command line (Oops!) I'm using dmd v2.074.0. In the future I'll include a compilable example. I was having problems with a class I made which is about 45 lines, that might be a lot of code for a post. But it seems to work now. This is good, I can have the comparisons work for any type without doing backflips. Thanks.
Jun 03
next sibling parent reply Mark <tigchelaarm mymacewan.ca> writes:
On Saturday, 3 June 2017 at 22:38:31 UTC, Mark wrote:
...
 Thanks.
Actually, I got another question, how Can I obtain the actual memory address of a class? I'll still need to solve the problem of taking ints/floats/reals etc., as well as structs and classes and sending them right/left in the BST. :/ Thanks again.
Jun 03
parent Mark <tigchelaarm mymacewan.ca> writes:
On Saturday, 3 June 2017 at 22:52:42 UTC, Mark wrote:

 Thanks again.
Nevermind, I got it.
Jun 03
prev sibling next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 3 June 2017 at 22:38:31 UTC, Mark wrote:

 In the future I'll include a compilable example. I was having 
 problems with a class I made which is about 45 lines, that 
 might be a lot of code for a post.
You can use external resources such as: https://d.godbolt.org/ https://dpaste.dzfl.pl to paste code there and then just post a link to a paste here.
Jun 03
parent Mark <tigchelaarm mymacewan.ca> writes:
On Saturday, 3 June 2017 at 22:53:51 UTC, Stanislav Blinov wrote:
 On Saturday, 3 June 2017 at 22:38:31 UTC, Mark wrote:

 In the future I'll include a compilable example. I was having 
 problems with a class I made which is about 45 lines, that 
 might be a lot of code for a post.
You can use external resources such as: https://d.godbolt.org/ https://dpaste.dzfl.pl to paste code there and then just post a link to a paste here.
I'll keep that in mind, thanks.
Jun 03
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/03/2017 03:38 PM, Mark wrote:

 Ok. So by using '==' it should compare the addresses of the objects?
That's the default behavior. You can change it with opEquals: http://ddili.org/ders/d.en/object.html#ix_object.opEquals I think you want to use the 'is' operator: http://ddili.org/ders/d.en/class.html#ix_class.is,%20operator It's better because 'is' can be used with null variables.
 about 45 lines, that might be a lot of code
 for a post.
Yeah. Minimal is good. :)
 how Can I obtain the actual memory address of a class?
You mean the memory address of a class object. ;) It's achieved with the special semantics of casting the class variable to void*: class C { int i; } void info(C o) { import std.stdio; writefln(" Object at %s,\n" ~ "i member at %s\n", cast(void*)o, &o.i); } void main() { auto a = new C(); auto b = new C(); a.info(); b.info(); } Sample output on my system: Object at 7F810AA53060, i member at 7F810AA53070 Object at 7F810AA53080, i member at 7F810AA53090 The difference of 16 bytes are from vtbl pointer and the monitor. (I think the latter is a kind of a lizard, which nobody actually uses. :p) Ali
Jun 03
parent Mark <tigchelaarm mymacewan.ca> writes:
On Saturday, 3 June 2017 at 23:32:44 UTC, Ali Çehreli wrote:
...
 Ali
Awesome, that might be handy in the near future. Thanks.
Jun 03
prev sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Sat, Jun 03, 2017 at 10:38:31PM +0000, Mark via Digitalmars-d-learn wrote:
[...]
 Ok. So by using '==' it should compare the addresses of the objects?
[...] No, `==` is for comparing the *contents* of the objects. You need to implement opEquals() for the objects being compared in order to define how the contents will be compared. If you want to compare *addresses*, use `is`: Object a = new Object(...); Object b = a; // b is a reference to the same object as a assert(b is a); In this case there is no need to implement anything else, since comparing addresses is simple. T -- "No, John. I want formats that are actually useful, rather than over-featured megaliths that address all questions by piling on ridiculous internal links in forms which are hideously over-complex." -- Simon St. Laurent on xml-dev
Jun 03