C++11 virtual destructors and auto generation of move special functions

  1. No, a defaulted destructor is still considered user defined, so it will prevent the generation of move operations. Also declare the move operations default-ed to make the compiler generate them.

  2. You need to only declare the move operations as default-ed in the base class. In the derived class, the destructor won’t be user defined anymore (unless you explicitly say so), so the move operations won’t be deleted.

So what I’d do is the following:

class Base
{
    virtual ~Base() = default;
    Base(Base&&) = default;
    Base& operator=(Base&&) = default;
    // probably need to think about copy operations also, as the move disables them
    Base(const Base&) = default;
    Base& operator=(const Base&) = default;
};

I highly recommend this talk by the person who contributed probably the most to the move semantics: http://www.slideshare.net/ripplelabs/howard-hinnant-accu2014

Or, if you can get your hands on, you should read the Item 17: Understand special member function generation from Scott Meyers’ excellent book Effective Modern C++. This issue is excellently explained.

PS: I think you should think a bit more about your base classes. Most of the time, you should use abstract classes, so there will be no need to copy/move instances of them.

PSS: I think by default destructors are marked noexcept in C++11/14, so not explicitly specifying it shouldn’t cause any problems:

Inheriting constructors and the implicitly-declared default
constructors, copy constructors, move constructors, destructors,
copy-assignment operators, move-assignment operators are all
noexcept(true) by default, unless they are required to call a function
that is noexcept(false), in which case these functions are
noexcept(false).

Leave a Comment