Can I call the default opAssign after overloading opAssign?

Era Scarecrow rtcvb32 at yahoo.com
Sat Nov 24 12:47:16 PST 2012


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]


More information about the Digitalmars-d-learn mailing list