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