移动构造函数是否会更改"this"指向的内存?



我对移动构造函数C++有些困惑。如果编译器隐式合成移动构造函数,则此移动构造函数将执行什么操作?它只会使"this"指向用于初始化的对象吗? 有一个例子:

struct Foo {
int i;
int *ptr;
};
Foo x;
Foo y(std::move(x));

隐式合成的 Move 构造函数是否只会使thisy指向x所在的内存?如果是这样,如何确保x在移动后是可破坏的(如果x被销毁,y的成员是否有效)?如果不是,y的移动构造函数如何工作?

式合成的移动构造函数会让它在 y 中指向 x 所在的内存吗?

合成的移动 ctor将按成员方式将其参数的数据成员(此处x)移动到正在创建的对象(此处y)。

另请注意,对于内置类型(如int),移动与复制相同。


如何确保 X 在移动后是可破坏的

由于 move 与内置类型的复制相同,因此xy是相互独立的。因此,当x被销毁时y不会受到影响。


合成的移动构造函数会将xptr设置为nullptr吗?

不,合成移动 ctor 不会为您执行此操作。它只会按成员移动数据成员。对于内置类型,这意味着与复制相同。


如果它不这样做,那么xptr仍将指向yptr指向的内存,那么您无法安全地销毁x.

在这种情况下,您需要编写一个用户定义的移动 ctor,该 ctor显式将xptr设置为nullptr,以便在销毁x时,y不受影响。

式合成的移动构造函数会让它在 y 中指向 x 所在的内存吗?

正如 Anoop 所指出的,它将在要移动的源的每个成员上成员(x)成员调用移动构造函数(ythis,如果你想象自己"在"合成的移动构造函数中

)。所以在你的例子中:

  • intx.i将移至y.i(this->i)
  • int*x.ptr将移至y.ptr(this->ptr)。

请注意,这些特定移动将通过复制来执行。

如何保证移动后X是可破坏的(如果X被销毁,Y中的成员是否有效)?

它总是可破坏的。 至于它是否"有效",这取决于。默认的移动构造实际上是一个副本。 现在有两个对象指向x.ptr指向的任何内容。 如果该intx"拥有"的资源(也许该资源是堆上以 0 结尾的整数字符串),那么您只是"共享"了该资源。

如果您不想"共享"它,那么您可以为Foo显式编写一个移动构造函数,该构造函数重置"moved-from"对象的指针,或者以某种方式将其标记为无效。

struct Foo {
...
Foo(Foo&& other) {
this->i = other.i;
this->ptr = other.ptr;
other.ptr = nullptr;
}
}

一般来说,最好不要依赖"移动"的对象,即确保它们尽快被销毁。

最新更新