是否为派生类生成了移动构造函数/赋值运算符

时间:2012-05-22 10:16:26

标签: c++ c++11

如果类X派生自类Y,类Y具有以下任何一个:

  • 用户声明的复制构造函数,
  • 用户声明的复制赋值运算符
  • 用户声明的析构函数
  • 用户声明的移动构造函数,
  • 用户声明的移动分配运算符

对于类X,是否会隐式默认移动构造函数和移动赋值运算符,前提是它没有声明上述内容?

e.g。

struct Y
{
     virtual ~Y() {}

     // .... stuff

};

struct X : public Y
{
   // ... stuff but no destructor, 
   //               no copy/move assignment operator 
   //               no copy/move constructor

   // will X have a default move constructor / assignment operator?
};

我目前正在使用gcc,但我主要感兴趣的是正确的行为(与特定编译器是否符合标准相反)。

2 个答案:

答案 0 :(得分:3)

就派生类而言,属性或基类具有用户定义或隐式特殊函数的事实无关紧要。重要的是他们的存在。

兼容的C ++ 11编译器应该自动为结构和类提供移动构造函数和赋值运算符,如果可能的话(标准中明确定义),即使只有具有动态分配缓冲区的类才能真正从中受益(移动int只是复制它。)

因此,如果您的类嵌入了std::stringstd::unique_ptr(例如),那么其移动构造函数将调用嵌入的stringunique_ptr移动构造函数将是高效的...免费。

只需更改编译模式就可以略微提高性能。

答案 1 :(得分:2)

是的,它们是§12.8.9:

如果类X的定义没有显式声明移动构造函数,则会隐式声明一个 当且仅当

时默认为
  • X没有用户声明的复制构造函数,
  • X没有用户声明的复制赋值运算符
  • X没有用户声明的移动赋值运算符
  • X没有用户声明的析构函数,
  • 移动构造函数不会被隐式定义为已删除。

和§12.8.10

类X的隐式声明的移动构造函数将具有

形式
X::X(X&&)

同样,对于12.8.20中的移动赋值运算符:

如果类X的定义没有显式声明一个移动赋值运算符,当且仅当

时,才会隐式声明一个默认值。
  • X没有用户声明的复制构造函数,
  • X没有用户声明的移动构造函数,
  • X没有用户声明的复制赋值运算符
  • X没有用户声明的析构函数,
  • 移动赋值运算符不会被隐式定义为已删除。

基类不会直接进入。