Search code examples
c++c++11move-semanticsvirtual-destructor

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


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?


Solution

  • 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 if

    • 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.

    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:

    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.