在C ++ 11中,如果基类定义了自己的移动(复制)构造函数(赋值运算符),它的子类是否需要在调用基类的位置定义自己的移动(复制)构造函数(赋值运算符) #39;显式调用相应的构造函数/运算符?
每次都清楚地定义构造函数,析构函数,移动/复制构造函数(赋值运算符)是不是一个好主意?
struct Base {
Base() {}
Base(Base&& o);
};
struct Sub : public Base {
Sub(Sub&& o) ; // Need I do it explicitly ? If not,what the compiler will do for me
};
答案 0 :(得分:4)
如果你没有在基类中指定一个默认的移动构造函数(some cases除外,编译器将生成一个默认的移动构造函数,例如,有一个带有删除的移动构造函数的基类)但是你应该在任何情况下调用明确基类'如果你有它的话:
Sub(Sub&& o) : Base(std::move(o))
答案 1 :(得分:1)
根据标准(N3797) 12.8 / 9复制和移动类对象[class.copy]:
如果
时,将隐式声明为默认值。class X
的定义未明确声明移动构造函数,则当且仅当- X没有用户声明的复制构造函数,
- X没有用户声明的复制赋值运算符
- X没有用户声明的移动赋值运算符,
- X没有用户声明的析构函数。
因此,如果您的class
符合上述要求,则会隐式声明默认移动构造函数。
如前所述,基类不了解任何子类。因此,是否在一个基类中声明移动构造函数对其子类中隐式生成移动构造函数没有影响。
至于它是否应该明确声明一个类的构造函数/析构函数等,那么这个很好article。
答案 2 :(得分:0)
不,你没有。我会像默认/复制构造函数一样自动生成。
来自this page,
隐式声明的移动构造函数
如果没有为类类型(struct,class或union)提供用户定义的移动构造函数,并且满足以下所有条件:
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 (until C++14) the implicitly-declared move constructor is not defined as deleted due to conditions detailed in the next section
然后编译器将一个移动构造函数声明为其类的内联公共成员,其签名为T :: T(T&&)。
一个类可以有多个移动构造函数,例如T :: T(const T&&)和T :: T(T&&)都是。如果存在一些用户定义的移动构造函数,则用户仍可以使用关键字default强制生成隐式声明的移动构造函数。
您的struct Sub
没有用户声明的副本构造函数,复制赋值运算符,移动赋值运算符或析构函数。
和
琐碎的移动构造函数
如果满足以下所有条件,则类T的移动构造函数是微不足道的:
It is not user-provided (meaning, it is implicitly-defined or defaulted), and if it is defaulted, its signature is the same as implicitly-defined T has no virtual member functions T has no virtual base classes The move constructor selected for every direct base of T is trivial The move constructor selected for every non-static class type (or array of class type) member of T is trivial T has no non-static data members of volatile-qualified type
(自C ++ 14起)
一个简单的移动构造函数是一个构造函数,它执行与普通复制构造函数相同的操作,即通过std :: memmove创建对象表示的副本。与C语言兼容的所有数据类型(POD类型)都是可以移动的。
隐式定义的移动构造函数
如果隐式声明的移动构造函数既未被删除也未被删除,则编译器会定义它(即,生成并编译函数体)。对于联合类型,隐式定义的移动构造函数复制对象表示(如std :: memmove)。 对于非联合类类型(类和结构),移动构造函数使用xvalue参数的直接初始化,以初始化顺序执行对象的基础和非静态成员的完全成员移动。
Base
的移动构造函数不是微不足道的(它是用户定义的)。因此,隐式定义的Sub
移动构造函数将作为“移动构造函数执行完全成员移动对象的基础和非静态成员,按其初始化顺序,使用使用xvalue参数直接初始化。“