Can I call the default opAssign after overloading opAssign?

Dan dbdavidson at yahoo.com
Sat Nov 24 14:39:24 PST 2012


On Saturday, 24 November 2012 at 20:47:17 UTC, Era Scarecrow 
wrote:
> On Friday, 23 November 2012 at 22:31:46 UTC, Rob T wrote:
>> That's VERY interesting indeed and originally I had no idea it 
>> would do this without a custom opAssign at each level.
>>
>> This kind of behavior *really* needs to be documented in 
>> precise detail, it's rather critical to know.
>
>  It IS documented. TDPL - pg. 248
> [quote]
>   The second step (the part with 'transitive field') of the 
> postblit copy process deserves a special mention. The rationale 
> for that behavior is [i]encapsulation[/i]-the postblit 
> constructor of a struct object must be called even when the 
> struct is embedded in another struct object. Consider, for 
> example, that we make Widget a member of another struct, which 
> in turn is a member of yet another struct:
>
> (included from pg. 246)
> [code]
> struct Widget {
>   private int[] array;
>   this(uint length) {
>     array = new int[length];
>   }
>   // postblit constructor
>   this(this){
>     array = array.dup;
>   }
>   //As Before
>   int get(size_t offset) { return array[offset]; }
>   void set(size_t offset, int value) { array[offset] = value; }
> }
>
> struct Widget2 {
>   Widget w1;
>   int x;
> }
>
> struct Widget3 {
>   Widget2 w2;
>   string name;
>   this(this) {
>     name = name ~ " (copy)";
>   }
> }
> [/code]
>
>   Now, if you want to copy around objects that contain Widgets, 
> it would be pretty bad if the compiler forgot to properly copy 
> the Widget subobjects. That's why when copying objects of type 
> Widget2, a call to this(this) is issued for the w subobject, 
> even though Widget2 does not intercept copying at all. Also, 
> when copying objects of type Widget3, again this(this) is 
> invoked for the field w1 of field w2. To Clarify:
>
> [code]
> unittest {
>   Widget2 a;
>   a.w1 = Widget(10);                  //Allocate some memory
>   auto b = a;                         // this(this) called for 
> b.w
>   assert(a.w1.array ~is b.w1.array);  // Pass
>
>   Widget3 c;
>   c.w2.w1 = Widget(20);
>   auto d = c;                           // this(this) for 
> d.w2.w1
>   assert(c.w.2.w.1.array !is d.w2.w1.array);  //pass
> }
> [/code]
> [/quote]

Good catch on this(this) - it is documented well. But I think the 
questionable part is on assignment, not copy construction via 
postblit. For assignment the postblit *is* being called and the 
language spec (not TDPL) glosses over that. Also, not mentioned 
in TDPL is what happens if you do implement your own opAssign. I 
think some of the magic goes away if I'm not mistaken (i.e. those 
well-crafted postblits will not be called). I think this should 
be documented as well.

Thanks
Dan


More information about the Digitalmars-d-learn mailing list