Can I call the default opAssign after overloading opAssign?

Dan dbdavidson at yahoo.com
Mon Nov 19 04:10:31 PST 2012


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