Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare the virtual destructor without breaking move and copy constructors

When adding a user defined default virtual destructor to a class like this..

class Foo
{
public:
    Foo();
    virtual ~Foo() = default;
};

.. It has the side effects of preventing auto generation of move constructors. Also auto generation of copy constructors is deprecated. A recommended way is to user define all constructors like this..

class Foo
{
public:
  Foo();
  virtual ~Foo() = default;
  Foo(const Foo& /* other */) = default;
  Foo&operator=(const Foo& /* other */) = default;
  Foo(Foo&& /* other */) = default;
  Foo&operator=(Foo&& /* other */) = default;
};

However, this is super verbose and unreadable. Are there any other solutions to this?

like image 599
Mathias Avatar asked Feb 01 '16 10:02

Mathias


Video Answer


1 Answers

First I would consider whether Foo really needs a virtual destructor. Maybe you can solve your problem in a type safe manner using a simple template, saving you from messing with pointers and casting and so on.

If you decide on making Foo virtual, then I would recommend this abstraction.

class VirtualDestructor
{
protected:
  VirtualDestructor() = default;
  virtual ~VirtualDestructor() = default;
  VirtualDestructor(const VirtualDestructor & /* other */) = default;
  VirtualDestructor &operator=(const VirtualDestructor & /* other */) = default;
  VirtualDestructor(VirtualDestructor && /* other */) = default;
  VirtualDestructor &operator=(VirtualDestructor && /* other */) = default;
};

Put this in a library in an appropriate namespace. Then you can keep Foo and all other virtual classes clean.

class Foo : VirtualDestructor
{
public:
    Foo();
};

The same technique can also be used when deleting for example copy constructors.

Edit: Compiler output and diff with original code

like image 159
Mathias Avatar answered Nov 15 '22 00:11

Mathias