我对移动构造函数C++有些困惑。如果编译器隐式合成移动构造函数,则此移动构造函数将执行什么操作?它只会使"this"指向用于初始化的对象吗? 有一个例子:
struct Foo {
int i;
int *ptr;
};
Foo x;
Foo y(std::move(x));
隐式合成的 Move 构造函数是否只会使this
y
指向x
所在的内存?如果是这样,如何确保x
在移动后是可破坏的(如果x
被销毁,y
的成员是否有效)?如果不是,y
的移动构造函数如何工作?
式合成的移动构造函数会让它在 y 中指向 x 所在的内存吗?
合成的移动 ctor将按成员方式将其参数的数据成员(此处x
)移动到正在创建的对象(此处y
)。
另请注意,对于内置类型(如int
),移动与复制相同。
如何确保 X 在移动后是可破坏的
由于 move 与内置类型的复制相同,因此x
和y
是相互独立的。因此,当x
被销毁时y
不会受到影响。
合成的移动构造函数会将
x
的ptr
设置为nullptr
吗?
不,合成移动 ctor 不会为您执行此操作。它只会按成员移动数据成员。对于内置类型,这意味着与复制相同。
如果它不这样做,那么
x
的ptr
仍将指向y
ptr
指向的内存,那么您无法安全地销毁x
.
在这种情况下,您需要编写一个用户定义的移动 ctor,该 ctor显式将x
的ptr
设置为nullptr
,以便在销毁x
时,y
不受影响。
式合成的移动构造函数会让它在 y 中指向 x 所在的内存吗?
正如 Anoop 所指出的,它将在要移动的源的每个成员上成员(x
)成员调用移动构造函数(y
或this
,如果你想象自己"在"合成的移动构造函数中
)。所以在你的例子中:
int
x.i
将移至y.i
(this->i
)int*
x.ptr
将移至y.ptr
(this->ptr
)。
请注意,这些特定移动将通过复制来执行。
如何保证移动后X是可破坏的(如果X被销毁,Y中的成员是否有效)?
它总是可破坏的。 至于它是否"有效",这取决于。默认的移动构造实际上是一个副本。 现在有两个对象指向x.ptr
指向的任何内容。 如果该int
是x
"拥有"的资源(也许该资源是堆上以 0 结尾的整数字符串),那么您只是"共享"了该资源。
如果您不想"共享"它,那么您可以为Foo
显式编写一个移动构造函数,该构造函数重置"moved-from"对象的指针,或者以某种方式将其标记为无效。
struct Foo {
...
Foo(Foo&& other) {
this->i = other.i;
this->ptr = other.ptr;
other.ptr = nullptr;
}
}
一般来说,最好不要依赖"移动"的对象,即确保它们尽快被销毁。