Can I call the default opAssign after overloading opAssign?

Dan dbdavidson at yahoo.com
Fri Nov 23 11:53:40 PST 2012


On Monday, 19 November 2012 at 12:10:32 UTC, Dan wrote:

Just following up to get confirmation. Hopefully Johnathan or 
similar expert can follow up.

Here is a strong statement:

If for any struct S you implement a postblit then there is no 
need to implement opAssign to get a working assignment operator 
from a type S because by design postblit is already called by 
default opAssign. This is the behavior I see, but I may be 
missing something since the language specification does not 
mention postblit, only blit.

Thanks
Dan

> On Monday, 19 November 2012 at 05:22:38 UTC, Jonathan M Davis 
> wrote:
>> On Monday, November 19, 2012 06:01:55 Rob T wrote:
>
>> postblit constructors and opAssign aren't really related. The 
>> postblit
>> constructor is used when a _new_ instance is being constructed 
>> (it plays the
>> same role as a copy constructor in C++). opAssign overloads 
>> the assignment
>> operator and is only used when the assignment operator is 
>> used, which does
>> _not_ happen when contstructing a new instance but only when 
>> replacing the
>> value of an instance with that of another.
>
> Is this correct? From a implementation point of view it looks 
> like opAssign is related to postblit in that it does call 
> postblit first.
> From the spec:
>     Struct assignment t=s is defined to be semantically 
> equivalent to:
>       t = S.opAssign(s);
>     where opAssign is a member function of S:
>     S* opAssign(S s)
>     {   ... bitcopy *this into tmp ...
>       ... bitcopy s into *this ...
>       ... call destructor on tmp ...
>       return this;
>     }
>
> It does not say postblit as well, but it does call it.
> When assigning one object into another it will first blit, then 
> custom postblit if you have written one. A benefit of this is, 
> if you want deep copy semantics and postblit does the work to 
> provide it - you do not need an opAssign at all, as your 
> postblit will be called. I think this is a step up over C++.
>
> The example below prints:
> ----------------------------------------------
> Begin assign
> postblit A
> End assign
> ----------------------------------------------
>
> import std.stdio;
> import std.traits;
>
> struct A {
>   this(this) { c = c.dup; writeln("postblit A"); }
>   char[] c;
>
> }
> struct B { A a; }
> struct C { B b; }
> struct D { C c; }
>
> void main() {
>   D d1, d2;
>   d1.c.b.a.c = ['a','b','c'];
>   writeln("Begin assign");
>   d2 = d1;
>   writeln("End assign");
> }




More information about the Digitalmars-d-learn mailing list