5

如果 X 类派生自 Y 类并且 Y 类具有以下任何一种:

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

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

例如

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,但我主要对正确的行为应该是什么感兴趣(而不是特定编译器是否符合标准)..

4

2 回答 2

3

就派生类而言,属性或基类具有用户定义或隐式特殊功能这一事实并不重要。重要的是他们的存在。

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

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

因此,只需更改编译模式即可略微提高性能。

于 2012-05-22T10:51:49.960 回答
2

是的,它们在 §12.8.9 中:

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

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

和§12.8.10

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

X::X(X&&)

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

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

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

基类不直接进入它。

于 2012-05-22T10:52:46.470 回答