will the implicitly synthesized move constructor just make this in y point to the memory that x is in?
As Anoop noted, it will memberwise call the move constructor on every member of the source to be moved (x
) onto the members of the destination (y
or this
if you imagine yourself "inside" that synthesized move constructor).
So in your example:
- the
int
x.i
will be moved onto y.i
(this->i
)
- the
int*
x.ptr
will be moved onto y.ptr
(this->ptr
).
Note that these particular moves will be performed by copying.
how to ensure that x is destructible after the move (if x is destroyed, will members in y be valid)?
It's always destructible. As to if it's "valid", it depends. The default move construction was actually a copy. Two objects now point at whatever x.ptr
pointed to. If that int
was a resource "owned" by x
(maybe the resource was a 0 terminated string of ints on the heap), then you've just "shared" that resource.
If you don't wish to "share" it then you could have explicitly written a move constructor for Foo
that resets the pointer of the "moved-from" object, or somehow marks it invalid.
struct Foo {
...
Foo(Foo&& other) {
this->i = other.i;
this->ptr = other.ptr;
other.ptr = nullptr;
}
}
In general, it's best not to rely on "moved from" objects at all, i.e. make sure they are destroyed as soon as possible.