Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 10, 2013 this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Is it expected behaviour that this code compiles and prints: this(this) this(this) ? [code] import std.stdio; static if (!is(typeof(writeln))) alias writefln writeln; struct vec2f { public: float x, y; this(this) { writeln("this(this)"); } } void main() { vec2f v1 = vec2f(0, 1); vec2f v2 = vec2f(2, 3); v2 = v1; vec2f v3 = v2; } [/code] while this code [code] import std.stdio; static if (!is(typeof(writeln))) alias writefln writeln; struct vec2f { public: float x, y; this(this) { writeln("this(this)"); } ref vec2f opAssign(ref const vec2f v) { writeln("opAssign"); this.x = v.x; this.y = v.y; return this; } } void main() { vec2f v1 = vec2f(0, 1); vec2f v2 = vec2f(2, 3); v2 = v1; vec2f v3 = v2; } [/code] prints: opAssign this(this) ? And what should I use, this(this) or opAssign? I thougth that it is unimportant, but that changed my mind: http://dpaste.dzfl.pl/36ce3688 |
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, 10 January 2013 at 23:03:30 UTC, Namespace wrote:
> And what should I use, this(this) or opAssign? I thougth that it is unimportant,
> but that changed my mind: http://dpaste.dzfl.pl/36ce3688
The default generated opAssign will postblit the other struct over itself, then destroy it's own (old) body (if a postblit occured):
import std.stdio;
//----
struct S
{
this(this) {
writeln("this(this)");
}
~this() {
writeln("~this");
}
}
void main()
{
S a, b;
writeln("Start");
a = b;
writeln("Finish");
}
//----
Produces
//----
Start
this(this) //Postblit a new copy
~this //Destroy the old body
Finish
~this
~this
//----
This is a very sweet deal: If you write a constructor (and optionally a destructor), then that's all you need for D to make things consistent. For example:
//----
import std.stdio;
struct S
{
int* p;
this(int i)
{
p = new int;
*p = i;
}
this(this)
{
int* p2 = new int;
*p2 = *p;
p = p2;
}
}
void main()
{
S a = S(1);
S b = S(2);
writeln("Start");
a = b;
assert(*a.p == 2);
assert(a.p != b.p);
writeln("Finish");
}
//----
Here, the default generate opAssign is *not* "stupid" and will not straight up assign the pointers. After the assignments, each struct will still have their own personal payload!
Now to answer your question:
If your object is a POD, the no need for opAssign.
If your object has a constructor, then the default opAssign should remain consistent with your construcor's behavior...
...BUT: you can still implement it yourself if (and only if) you need a custom behavior. In the above example, opAssign "worked", but it did needlessly re-alocate. This is the kind of situation where writing an opAssign is worth it.
|
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, 10 January 2013 at 23:03:30 UTC, Namespace wrote:
> Is it expected behaviour that this code compiles and prints:
I think it is. Postblit 'this(this)' occurs while initializing a variable from one, rather than copying. Which you also can compare against move symantics.
Correct me if i'm wrong.
struct S {
this(this) {writeln("this(this)"); }
void opAssign(ref S s) {writeln("opAssign ref/copy");}
void opAssign(S s) {writeln("opAssign move");}
}
//postblit
S s1;
S s2 = s1;
//opAssign ref (copy)
S s3;
s3 = s1;
//opAssign S (Move)
S func() {return S();}
s3 = func();
output:
this(this)
opAssign ref/copy
opAssign move
|
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, 10 January 2013 at 23:03:30 UTC, Namespace wrote:
> And what should I use, this(this) or opAssign? I thougth that it is unimportant,
> but that changed my mind: http://dpaste.dzfl.pl/36ce3688
BTW, answered to the best of my abilities, taking into account your link expired, so I don't have as much context as you tried to offer.
|
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 10 January 2013 at 23:30:35 UTC, monarch_dodra wrote: > On Thursday, 10 January 2013 at 23:03:30 UTC, Namespace wrote: >> And what should I use, this(this) or opAssign? I thougth that it is unimportant, >> but that changed my mind: http://dpaste.dzfl.pl/36ce3688 > > BTW, answered to the best of my abilities, taking into account your link expired, so I don't have as much context as you tried to offer. It is private, sorry. Here as public: http://dpaste.dzfl.pl/ab3c7a5c |
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to Era Scarecrow | Without a declared opAssign, this S s3; s3 = s1; also calls the postblit. That is strange. |
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, 10 January 2013 at 23:37:14 UTC, Namespace wrote:
> Without a declared opAssign, this
>
> S s3;
> s3 = s1;
>
> also calls the postblit. That is strange.
If there is no user declared opAssign, then opAssign is implemented in terms of postblit. It's designed that way.
This is kind of like C++'s copy and swap idiom, but built into the language.
|
January 10, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Thursday, 10 January 2013 at 23:37:14 UTC, Namespace wrote:
> Without a declared opAssign, this
>
> S s3;
> s3 = s1;
>
> also calls the postblit. That is strange.
Think of it like this: Blit means bit-by-bit copy, so a postblit is a function that is invoked on the result of every bit-by-bit copy operation. The default behavior for struct assignment is precisely to copy over the contents, so it makes sense for the postblit to be invoked in that case.
David
|
January 11, 2013 Re: this(this) / opAssign | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Friday, 11 January 2013 at 00:02:48 UTC, monarch_dodra wrote: > On Thursday, 10 January 2013 at 23:35:19 UTC, Namespace wrote: >> On Thursday, 10 January 2013 at 23:30:35 UTC, monarch_dodra wrote: >>> On Thursday, 10 January 2013 at 23:03:30 UTC, Namespace wrote: >>>> And what should I use, this(this) or opAssign? I thougth that it is unimportant, >>>> but that changed my mind: http://dpaste.dzfl.pl/36ce3688 >>> >>> BTW, answered to the best of my abilities, taking into account your link expired, so I don't have as much context as you tried to offer. >> >> It is private, sorry. >> Here as public: http://dpaste.dzfl.pl/ab3c7a5c > > Yeah, but if you re-arrange the tests, then you get opposite results... > http://dpaste.dzfl.pl/fork/c52f290a Sorry: http://dpaste.dzfl.pl/9ff9b84a |
Copyright © 1999-2021 by the D Language Foundation