首页 文章

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

提问于
浏览
27

受到帖子Why does destructor disable generation of implicit move methods?的启发,我想知道默认的虚拟析构函数是否也是如此,例如:

class WidgetBase // Base class of all widgets
{
    public:
        virtual ~WidgetBase() = default;
        // ...
};

由于该类旨在成为窗口小部件层次结构的基类,因此我必须定义其析构函数virtual,以避免在使用基类指针时出现内存泄漏和未定义的行为 . 另一方面,我不想阻止编译器自动生成移动操作 .

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

1 回答

  • 24

    是的,声明任何析构函数都会阻止移动构造函数的隐式声明 .

    N3337 [class.copy] / 9:如果类X的定义没有显式声明一个移动构造函数,当且仅当X没有用户声明的复制构造函数时,才会隐式声明为默认值,X不会有一个用户声明的复制赋值运算符,X没有用户声明的移动赋值运算符,X没有用户声明的析构函数,并且移动构造函数不会被隐式定义为已删除 .

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

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

    WidgetBase(WidgetBase&&) = default;
    

    请注意,这将依次将复制构造函数定义为 delete ,因此您还需要 default

    WidgetBase(const WidgetBase&) = default;
    

    复制和移动赋值运算符的规则也很相似,所以如果需要,你必须使用它们 .

相关问题