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