我对C++移动构造函数有一些困惑。如果编译器隐式地合成了一个移动构造函数,那么这个移动构造函数将做什么?它会直接将"this“指向用于初始化的对象吗?有一个例子:
struct Foo {
int i;
int *ptr;
};
Foo x;
Foo y(std::move(x));
隐式合成的move构造函数会使this
在y
中指向x
所在的内存吗?如果是,如何确保x
在移动后是可销毁的(如果x
被销毁,y
中的成员是否有效)?如果不是,y
的move构造函数是如何工作的?
发布于 2022-04-10 08:22:19
,隐式合成的move构造函数会在y中指向x所在的内存吗?
合成的移动ctor memberwise-move将其参数(在这里的x
)的数据成员与正在创建的对象(在这里的y
)联系起来。
另外,请注意,对于像int
这样的内置类型,move与复制是一样的。
如何确保x在移动后是可销毁的
因为move与内置类型的复制相同,所以x
和y
是相互独立的。因此,当x
被销毁时,y
不会受到影响。
综合移动构造函数会将
ptr
ofx
设置为nullptr
吗?
不,综合移动机不会为你这么做的。它只是按成员的方式移动数据成员。对于内置类型,这意味着与复制相同。
如果
不这样做,那么
ptr
ofx
仍然会指向ptr
ofy
所指向的内存,那么您就不能安全地销毁x
。
在这种情况下,您需要编写一个用户定义的移动ctor,它显式地将ptr
of x
设置为nullptr
,以便当x
被销毁时,y
不会受到影响。
发布于 2022-04-10 09:01:11
,隐式合成的move构造函数会在y中指向x所在的内存吗?
正如Anoop所指出的,它将按成员的方式调用要移动的源(x
)的每个成员上的移动构造函数到目标的成员(如果您想象自己“在”合成移动构造函数的“内部”中)。
所以在你的例子中:
(this->i
)
int
x.i
将被移动到y.i
int*
x.ptr
将被移动到y.ptr
y.ptr
注意,这些特殊的移动将通过复制来执行。
如何确保x在移动后是可销毁的(如果x被销毁,y中的成员是否有效)?
它总是可以毁灭的。至于是否“有效”,则视乎情况而定。默认的移动结构实际上是一个副本。现在有两个对象指向x.ptr
所指向的任何对象。如果该int
是x
“拥有”的资源(可能该资源是堆中以0结尾的ints字符串),那么您只需“共享”该资源。
如果您不希望“共享”它,那么您可以为Foo
显式地编写一个移动构造函数,该构造函数可以重置“moved”对象的指针,或者以某种方式将其标记为无效。
struct Foo {
...
Foo(Foo&& other) {
this->i = other.i;
this->ptr = other.ptr;
other.ptr = nullptr;
}
}
一般来说,最好不要依赖“移出”对象,即确保它们被尽快销毁。
https://stackoverflow.com/questions/71814853
复制相似问题