我可以将 std::move 与不提供移动构造函数的 class 一起使用吗?
can I use std::move with class that doesn't provide a move constructor?
我有一个 class 这样的:
class myClass
{
int x[1000];
public:
int &getx(int i)
{
return x[i];
}
}
请注意,我没有在这里提供移动结构。
如果我使用以下代码:
myClass A;
auto B=std::move(a);
是 A 移动到 B 还是由于我没有提供移动构造函数,A 被复制到 B?
对象有没有默认的移动构造函数?如果是,它如何处理指针和动态分配的数组?
为您的 class 生成了移动构造函数,因为您没有定义任何避免其生成的方法(作为用户定义的析构函数或复制构造函数)
自动生成的移动构造函数将移动每个成员。对于int[1000]
相当于复制。
您的问题类似于。请注意 std::move 只是一个转换。您的值 a 将被转换为右值引用,但在您的情况下,原始对象不会被掠夺或偷窃。
要正确使用 API 或成语,您必须将其用于正确的事情。搬家最有意义,例如。 class 个对象,其中大部分对象数据分配在堆上。这样的对象很容易被窃取,'move' 可以让被窃取的对象保持一个明确的状态。典型的例子可能是例如某种类型的字符串 class,堆上有字符串数据。
在你的情况下,你希望发生什么?假设 a 是某个函数中的局部变量,即假设 a 在堆栈上。假设 b 是全局或文件范围或匿名命名空间变量,即不在堆栈上。从 a 移动到 b 时,您希望发生什么?
对于一个字符串,偷窃是有道理的。对于你的情况,偷窃是荒谬的。
虽然您没有提供显式移动构造函数,但编译器为您提供了隐式移动构造函数。
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
- X does not have a user-declared copy constructor, and
- X does not have a user-declared copy assignment operator,
- X does not have a user-declared move assignment operator,
- X does not have a user-declared destructor, and
- the move constructor would not be implicitly defined as deleted.
所以你的问题的答案是:不,A没有被复制到B。
不清楚你在其他问题中问的是什么。请详细说明。
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- There are no user-declared copy constructors.
- There are no user-declared copy assignment operators.
- There are no user-declared move assignment operators.
- There are no user-declared destructors
then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
基本上,是的,只要您不定义复制构造函数、复制赋值重载、移动赋值重载或析构函数,就会创建默认的移动构造函数。否则,您必须自己定义行为或使用:
class_name ( class_name && ) = default;
这将显式声明移动构造函数的默认版本。
Is there any default move constructor for an object?
在你的情况下是的。对于任何类型 T
,仅当满足某些条件时才会隐式声明移动构造函数。可以在 cpperference.com.
查看更多详细信息
If yes, how it does work with pointers and dynamically allocated arrays?
默认实现将制作指针的浅表副本。结果,不止一个对象将指向动态分配的数组。那会导致问题。有关该主题的更多信息,请参阅 The Rule of Three。
如果您有指向动态分配数组的指针,您需要:
- 提供一个明确定义的复制构造函数,它对动态分配的数组做正确的事情。这样做的副作用是默认的移动构造函数将被隐式删除。 and/or
- 提供一个显式定义的移动构造函数,您可以在其中适当地移动动态分配的数组的所有权。
我有一个 class 这样的:
class myClass
{
int x[1000];
public:
int &getx(int i)
{
return x[i];
}
}
请注意,我没有在这里提供移动结构。
如果我使用以下代码:
myClass A;
auto B=std::move(a);
是 A 移动到 B 还是由于我没有提供移动构造函数,A 被复制到 B?
对象有没有默认的移动构造函数?如果是,它如何处理指针和动态分配的数组?
为您的 class 生成了移动构造函数,因为您没有定义任何避免其生成的方法(作为用户定义的析构函数或复制构造函数)
自动生成的移动构造函数将移动每个成员。对于int[1000]
相当于复制。
您的问题类似于
要正确使用 API 或成语,您必须将其用于正确的事情。搬家最有意义,例如。 class 个对象,其中大部分对象数据分配在堆上。这样的对象很容易被窃取,'move' 可以让被窃取的对象保持一个明确的状态。典型的例子可能是例如某种类型的字符串 class,堆上有字符串数据。
在你的情况下,你希望发生什么?假设 a 是某个函数中的局部变量,即假设 a 在堆栈上。假设 b 是全局或文件范围或匿名命名空间变量,即不在堆栈上。从 a 移动到 b 时,您希望发生什么?
对于一个字符串,偷窃是有道理的。对于你的情况,偷窃是荒谬的。
虽然您没有提供显式移动构造函数,但编译器为您提供了隐式移动构造函数。
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
- X does not have a user-declared copy constructor, and
- X does not have a user-declared copy assignment operator,
- X does not have a user-declared move assignment operator,
- X does not have a user-declared destructor, and
- the move constructor would not be implicitly defined as deleted.
所以你的问题的答案是:不,A没有被复制到B。
不清楚你在其他问题中问的是什么。请详细说明。
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- There are no user-declared copy constructors.
- There are no user-declared copy assignment operators.
- There are no user-declared move assignment operators.
- There are no user-declared destructors
then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
基本上,是的,只要您不定义复制构造函数、复制赋值重载、移动赋值重载或析构函数,就会创建默认的移动构造函数。否则,您必须自己定义行为或使用:
class_name ( class_name && ) = default;
这将显式声明移动构造函数的默认版本。
Is there any default move constructor for an object?
在你的情况下是的。对于任何类型 T
,仅当满足某些条件时才会隐式声明移动构造函数。可以在 cpperference.com.
If yes, how it does work with pointers and dynamically allocated arrays?
默认实现将制作指针的浅表副本。结果,不止一个对象将指向动态分配的数组。那会导致问题。有关该主题的更多信息,请参阅 The Rule of Three。
如果您有指向动态分配数组的指针,您需要:
- 提供一个明确定义的复制构造函数,它对动态分配的数组做正确的事情。这样做的副作用是默认的移动构造函数将被隐式删除。 and/or
- 提供一个显式定义的移动构造函数,您可以在其中适当地移动动态分配的数组的所有权。