www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What should opAssign return?

reply Charles D Hixson <charleshixsn earthlink.net> writes:
What I would expect is:

class A
{
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
}

but the only examples that I can find (variant.d) return *this 
... which leaves me quite confused.  Is this something special 
that Variant is doing to allow it to handle multiple types (I 
didn't follow the internals), or do I have what is supposed to 
be returned wrong?
Oct 22 2007
next sibling parent reply Nathan Reed <nathaniel.reed gmail.com> writes:
Charles D Hixson wrote:
 What I would expect is:
 
 class A
 {
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
 }
 
 but the only examples that I can find (variant.d) return *this ... which 
 leaves me quite confused.  Is this something special that Variant is 
 doing to allow it to handle multiple types (I didn't follow the 
 internals), or do I have what is supposed to be returned wrong?

'this' is a pointer to the object, so '*this' is (a reference to) the actual object. Thanks, Nathan Reed
Oct 22 2007
parent reply Charles D Hixson <charleshixsn earthlink.net> writes:
Nathan Reed wrote:
 Charles D Hixson wrote:
 What I would expect is:

 class A
 {
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
 }

 but the only examples that I can find (variant.d) return *this ... 
 which leaves me quite confused.  Is this something special that 
 Variant is doing to allow it to handle multiple types (I didn't follow 
 the internals), or do I have what is supposed to be returned wrong?

'this' is a pointer to the object, so '*this' is (a reference to) the actual object. Thanks, Nathan Reed

Sorry, I'm sure you think you answered the question, but I'm as confused as before. Are you saying that *this is the correct thing to return? (I know that "*this" means a pointer to this, and that "this" is a pointer to the object being created, but that doesn't help me at the point where I am confused. I still don't know what should be returned.)
Oct 22 2007
parent reply "Rioshin an'Harthen" <rharth75 hotmail.com> writes:
"Charles D Hixson" <charleshixsn earthlink.net> kirjoitti viestissä 
news:ffk5i4$2led$1 digitalmars.com...
 Nathan Reed wrote:
 Charles D Hixson wrote:
 What I would expect is:

 class A
 {
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
 }

 but the only examples that I can find (variant.d) return *this ... which 
 leaves me quite confused.  Is this something special that Variant is 
 doing to allow it to handle multiple types (I didn't follow the 
 internals), or do I have what is supposed to be returned wrong?

'this' is a pointer to the object, so '*this' is (a reference to) the actual object. Thanks, Nathan Reed

Sorry, I'm sure you think you answered the question, but I'm as confused as before. Are you saying that *this is the correct thing to return? (I know that "*this" means a pointer to this, and that "this" is a pointer to the object being created, but that doesn't help me at the point where I am confused. I still don't know what should be returned.)

this is a pointer to the object, and the unary asterisk (*) is the dereferencing operator. Thus, say you have something like int nInt = 42; int* pInt = &nInt; writeln(*pInt); , then nInt gets the value 42, the pointer pInt gets the address of nInt and the call to writeln dereferences the pointer, printing 42. To take this back to the *this, the dereferencing operator in front of the this pointer dereferences the pointer, returning the actual object the this pointer is pointing to. To reiterate: this is a pointer to the object being created, while *this is the actual object being created. Let's say the type of the object is A, as you had above. Now, this is the same as A*, and *this, which dereferences the pointer so that the actual object is visible, has the type A. In comparison with C, let's say you have a pointer to a B: typedef struct _B { int value; } B; B* pB; Now you can access the member 'value' with B->value or equally with (*B).value where -> is a dereferencing member access and . is a normal member access. The * before the B again does the dereferencing, so -> is basically a shorthand notation. However, compared to C, D automatically dereferences a pointer when accessing its' members; this, however, doesn't happen when returning an object type, so in the original example class A { A opAssign(A a) { return this; } } the return statement is trying to return a pointer to A, when the method signature says to return an A. Thus the dereferencing in variant.d, so that the return statement returns *this instead.
Oct 23 2007
parent BCS <ao pathlink.com> writes:
Reply to Rioshin an'Harthen,

 class A
 {
 A opAssign(A a)
 {
 return this;
 }
 }
 the return statement is trying to return a pointer to A, when the
 method signature says to return an A. Thus the dereferencing in
 variant.d, so that the return statement returns *this instead.
 

fails: the type A is already a pointer to an object (because it is a class) so the type of "this" is "A" not "A*".
Oct 23 2007
prev sibling parent reply downs <default_357-line yahoo.de> writes:
Charles D Hixson wrote:
 What I would expect is:
 
 class A
 {
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
 }
 
 but the only examples that I can find (variant.d) return *this ... which
 leaves me quite confused.  Is this something special that Variant is
 doing to allow it to handle multiple types (I didn't follow the
 internals), or do I have what is supposed to be returned wrong?

The this of a struct is a pointer. Ergo it has to dereference it, since opAssign returns the assignee for purposes of assignment chaining (a=b=c). Hope that clears things up. --downs
Oct 23 2007
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"downs" <default_357-line yahoo.de> wrote in message 
news:ffkf66$6cr$1 digitalmars.com...
 Charles D Hixson wrote:
 What I would expect is:

 class A
 {
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
 }

 but the only examples that I can find (variant.d) return *this ... which
 leaves me quite confused.  Is this something special that Variant is
 doing to allow it to handle multiple types (I didn't follow the
 internals), or do I have what is supposed to be returned wrong?

The this of a struct is a pointer. Ergo it has to dereference it, since opAssign returns the assignee for purposes of assignment chaining (a=b=c). Hope that clears things up. --downs

To take it one step further, what you have is correct for classes, what Variant has is correct for structures. The this member (which strangely, I can't find the documentation for on digital mars' site) is a reference for a class, and is a pointer for a struct. Since the return value for opAssign on a class is a reference, you return this. Since the return value for opAssign is a struct, not a pointer to a struct, you must return *this. -Steve
Oct 23 2007
prev sibling parent Charles D Hixson <charleshixsn earthlink.net> writes:
downs wrote:
 Charles D Hixson wrote:
 What I would expect is:

 class A
 {
   A opAssign(A a)
   {
      // do stuff here
      return this;
   }
 }

 but the only examples that I can find (variant.d) return *this ... which
 leaves me quite confused.  Is this something special that Variant is
 doing to allow it to handle multiple types (I didn't follow the
 internals), or do I have what is supposed to be returned wrong?

The this of a struct is a pointer. Ergo it has to dereference it, since opAssign returns the assignee for purposes of assignment chaining (a=b=c). Hope that clears things up. --downs

Oct 23 2007