默认的虚拟析构函数是否会阻止编译器生成的移动操作? [英] Does a default virtual destructor prevent compiler-generated move operations?

查看:291
本文介绍了默认的虚拟析构函数是否会阻止编译器生成的移动操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

受帖子 ="a href =" https://stackoverflow.com/questions/33932824/why-destructor-disabling-the-generation-of-implicit-move-functions>的启发隐式移动方法的生成? ,我想知道默认虚拟析构函数是否同样适用,例如

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.

默认的虚拟析构函数会阻止编译器生成的移动操作吗?

Does a default virtual destructor prevent compiler-generated move operations?

推荐答案

是的,声明任何析构函数将阻止对move构造函数进行隐式声明.

Yes, declaring any destructor will prevent the implicit-declaration of the move constructor.

N3337 [class.copy]/9:如果类X的定义未明确声明move构造函数,则将隐式声明一个move构造函数 且仅当且仅当

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 if

  • X没有用户声明的副本构造函数,
  • X没有用户声明的副本分配运算符,
  • X没有用户声明的移动分配运算符,
  • X没有用户声明的析构函数,并且
  • move构造函数不会隐式定义为已删除.
  • X does not have a user-declared copy constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator,
  • X does not have a user-declared destructor, and
  • the move constructor would not be implicitly defined as deleted.

声明析构函数并将其定义为default视为用户声明的.

Declaring the destructor and defining it as default counts as user-declared.

您需要声明move构造函数并将其自己定义为default:

You'll need to declare the move constructor and define it as default yourself:

WidgetBase(WidgetBase&&) = default;

请注意,这反过来会将副本构造函数定义为delete,因此您也需要default该副本构造函数:

Note that this will in turn define the copy constructor as delete, so you'll need to default that one too:

WidgetBase(const WidgetBase&) = default;

复制和移动分配运算符的规则也非常相似,因此如果需要它们,您必须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.

这篇关于默认的虚拟析构函数是否会阻止编译器生成的移动操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆