我有一个这样的课程:
class myClass
{
int x[1000];
public:
int &getx(int i)
{
return x[i];
}
}
请注意,我这里没有提供移动构造。
如果我使用以下代码:
myClass A;
auto B=std::move(a);
A移动到B还是因为我没有提供移动构造函数,A被复制到B?
是否有对象的默认移动构造函数?如果是,它如何使用指针和动态分配的数组?
答案 0 :(得分:2)
虽然您没有提供显式移动构造函数,但编译器为您提供了隐式移动构造函数。
如果类X的定义没有显式声明一个移动构造函数,那么当且仅当
时,才会隐式声明一个默认值。
- X没有用户声明的复制构造函数,
- X没有用户声明的复制赋值运算符
- X没有用户声明的移动赋值运算符
- X没有用户声明的析构函数,
- 移动构造函数不会被隐式定义为已删除。
所以你问题的答案是:不,A不会复制到B。
目前尚不清楚您在其他问题中提出的问题。请详细说明。
答案 1 :(得分:0)
为您的类生成移动构造函数,因为您没有定义任何避免生成它的方法(如用户定义的析构函数或复制构造函数)
自动生成的移动构造函数将移动每个成员。对于int[1000]
,它等同于复制。
答案 2 :(得分:0)
您的问题与this one类似。请注意,std :: move只是一个强制转换。您的值 a 将被转换为右值引用,但在您的情况下,原始对象不会被掠夺或被盗。
要正确使用API或习惯用法,您必须将其用于正确的事情。移动对于例如移动最有意义类对象,其中大量对象数据在堆上分配。这样的物体很容易被盗,并且“移动”可以使被盗物体处于明确定义的状态。规范的例子可以是例如某种类型的字符串类,在堆上有字符串数据。
在你的情况下,你想要发生什么?假设 a 是某个函数中的局部变量,即假设 a 在堆栈中。假设 b 是全局或文件范围或匿名命名空间变量,即不在堆栈上。从 a 移动到 b 时,您希望发生什么?
对于一个字符串,盗窃是有道理的。对于你的情况,盗窃是荒谬的。
答案 3 :(得分:0)
如果没有为类类型(struct,class或union)提供用户定义的移动构造函数,并且满足以下所有条件:
- 没有用户声明的副本构造函数。
- 没有用户声明的复制赋值运算符。
- 没有用户声明的移动分配操作符。
- 没有用户声明的析构函数
然后编译器将一个移动构造函数声明为其类的非显式内联公共成员,其签名为T :: T(T&&)。
基本上,只要您没有定义复制构造函数,复制赋值重载,移动赋值重载或析构函数,就会创建默认移动构造函数。否则,您必须自己定义行为或使用:
class_name ( class_name && ) = default;
它将显式声明移动构造函数的默认版本。
答案 4 :(得分:0)
是否有对象的默认移动构造函数?
在您的情况下是的。对于任何类型T
,只有在满足某些条件时才会隐式声明移动构造函数。有关详细信息,请参阅cpperference.com。
如果是,它如何使用指针和动态分配的数组?
默认实现将生成指针的浅表副本。因此,多个对象将指向动态分配的数组。这将导致问题。有关此主题的更多信息,请参阅The Rule of Three。
如果指针指向动态分配的数组,则需要: