Inspired by the post Why does destructor disable generation of implicit move methods?, I was wondering if the same is true for the default virtual destructor, e.g.
受帖子的启发为什么析构函数会禁用隐式移动方法的生成?我想知道默认的虚拟析构函数是否也是如此,例如
class WidgetBase // Base class of all widgets
{
public:
virtual ~WidgetBase() = default;
// ...
};
As the class is intended to be a base class of a widget hierarchy I have to define its destructor virtual to avoid memory leaks and undefined behavior when working with base class pointers. On the other hand I don't want to prevent the compiler from automatically generating move operations.
由于该类旨在成为窗口小部件层次结构的基类,因此我必须定义其析构函数virtual,以避免在使用基类指针时出现内存泄漏和未定义的行为。另一方面,我不想阻止编译器自动生成移动操作。
Does a default virtual destructor prevent compiler-generated move operations?
默认的虚拟析构函数是否会阻止编译器生成的移动操作?
1 个解决方案
#1
22
Yes, declaring any destructor will prevent the implicit-declaration of the move constructor.
是的,声明任何析构函数都会阻止移动构造函数的隐式声明。
N3337 [class.copy]/9:
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only ifN3337 [class.copy] / 9:如果类X的定义没有显式声明一个移动构造函数,那么当且仅当一个移动构造函数被隐式声明为默认值时
- X does not have a user-declared copy constructor,
- X没有用户声明的复制构造函数,
- X does not have a user-declared copy assignment operator,
- X没有用户声明的复制赋值运算符,
- X does not have a user-declared move assignment operator,
- X没有用户声明的移动赋值运算符,
- X does not have a user-declared destructor, and
- X没有用户声明的析构函数,和
- the move constructor would not be implicitly defined as deleted.
- 移动构造函数不会被隐式定义为已删除。
Declaring the destructor and defining it as default
counts as user-declared.
声明析构函数并将其定义为默认值计为用户声明的。
You'll need to declare the move constructor and define it as default
yourself:
您需要声明移动构造函数并将其自己定义为默认值:
WidgetBase(WidgetBase&&) = default;
Note that this will in turn define the copy constructor as delete
, so you'll need to default
that one too:
请注意,这将依次将复制构造函数定义为delete,因此您还需要默认该复制构造函数:
WidgetBase(const WidgetBase&) = default;
The rules for copy and move assignment operators are pretty similar as well, so you'll have to default
them if you want them.
复制和移动赋值运算符的规则也非常相似,因此如果需要,您必须默认它们。
#1
22
Yes, declaring any destructor will prevent the implicit-declaration of the move constructor.
是的,声明任何析构函数都会阻止移动构造函数的隐式声明。
N3337 [class.copy]/9:
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only ifN3337 [class.copy] / 9:如果类X的定义没有显式声明一个移动构造函数,那么当且仅当一个移动构造函数被隐式声明为默认值时
- X does not have a user-declared copy constructor,
- X没有用户声明的复制构造函数,
- X does not have a user-declared copy assignment operator,
- X没有用户声明的复制赋值运算符,
- X does not have a user-declared move assignment operator,
- X没有用户声明的移动赋值运算符,
- X does not have a user-declared destructor, and
- X没有用户声明的析构函数,和
- the move constructor would not be implicitly defined as deleted.
- 移动构造函数不会被隐式定义为已删除。
Declaring the destructor and defining it as default
counts as user-declared.
声明析构函数并将其定义为默认值计为用户声明的。
You'll need to declare the move constructor and define it as default
yourself:
您需要声明移动构造函数并将其自己定义为默认值:
WidgetBase(WidgetBase&&) = default;
Note that this will in turn define the copy constructor as delete
, so you'll need to default
that one too:
请注意,这将依次将复制构造函数定义为delete,因此您还需要默认该复制构造函数:
WidgetBase(const WidgetBase&) = default;
The rules for copy and move assignment operators are pretty similar as well, so you'll have to default
them if you want them.
复制和移动赋值运算符的规则也非常相似,因此如果需要,您必须默认它们。