www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opAssign for most struct assignment calls not executed

reply Timoses <timosesu gmail.com> writes:
What am I missing?

import std.stdio;

struct A
{
     int value;

     A opAssign(A a)
     {
         writeln(" Assigning");
         return this;             // I know this makes little 
sense, just for illustration
     }
}

class B
{
     A member;

     this(A a)
     {
         this.member = a; // specifically aiming towards this 
assignment...
     }
}

void main()
{
     A a = A(1);
     A aa = A(2);

     A aaa = a;

     auto clas = new B(a);

     writeln("Only this works:");
     aaa = a;
     writeln("or");
     A aaaa;
     aaaa = aa;
}


Output:
Only this works:
  Assigning
or
  Assigning


Note that before "Only this works:" nothing was written.

How can I overwrite the opAssign operator??
I'm sure I'm missing something...
Nov 23
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 23 November 2017 at 15:26:03 UTC, Timoses wrote:
     A member;

     this(A a)
     {
         this.member = a; // specifically aiming towards this 
 assignment...
That's not assignment, that's construction. opAssign is only called when you assign over a struct object that already exists. If there isn't an existing object in the variable already, it instead calls a constructor. A a = A(); // construction, there is no existing a to call A a; // construction done here... a = x; // so this is now assignment over the existing object Sometimes, they look the same, as in your case, but since you are assigning a member for the first time inside a constructor, it still counts as construction of the child object instead of assignment over an existing object.
Nov 23
prev sibling parent reply Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Thursday, 23 November 2017 at 15:26:03 UTC, Timoses wrote:
     A aaa = a;
That's initialization, not assignment, which is subtly different. It will call the postblit on aaa instead of opAssign. A postblit can be defined this way: this(this) { } There is no way to access the original a from the postblit. All fields have already been copied, you can use it to duplicate reference types, increment reference counts, and other things like that.
Nov 23
parent Timoses <timosesu gmail.com> writes:
On Thursday, 23 November 2017 at 15:45:17 UTC, Rene Zwanenburg 
wrote:
 On Thursday, 23 November 2017 at 15:26:03 UTC, Timoses wrote:
     A aaa = a;
That's initialization, not assignment, which is subtly different. It will call the postblit on aaa instead of opAssign. A postblit can be defined this way: this(this) { } There is no way to access the original a from the postblit. All fields have already been copied, you can use it to duplicate reference types, increment reference counts, and other things like that.
Wow, that's great! Thanks for the clarification you two! For reference: https://dlang.org/spec/struct.html#struct-postblit http://ddili.org/ders/d.en/special_functions.html
Nov 23