Nikos Athanasiou
Nikos Athanasiou

Reputation: 31549

What are defaulted destructors used for?

I can understand defaulted constructors, since user defined constructors will disable the compiler generated ones making the object non trivially copyable etc.

In the destructor case, apart from changing access category, what use is there to define a defaulted destructor considering that no user defined member function can disable them (you can't overload destructors anyway) ?

// Which version should I choose ? 
struct Example 
{
    //1. ~Example() = default; 
    //2. ~Example() {}
    //3. 
}; 

Even in the case of virtual destructors, defaulting them would not make them trivial so what good is it doing it?

Upvotes: 3

Views: 517

Answers (4)

Jean-Bernard Jansen
Jean-Bernard Jansen

Reputation: 7870

As mentioned by Nikos Athanasiou in a comment, a default constructor makes the type trivially destructible, where a user defined one does not. A little code sample will show it:

#include <iostream>
#include <type_traits>

struct A { ~A() = default; };
struct B { ~B() {} };
struct C { ~C() noexcept {} };

int main() {
  std::cout
    << std::is_trivially_destructible<A>::value
    << std::is_trivially_destructible<B>::value
    << std::is_trivially_destructible<C>::value
    << std::endl;
  return 0;
}

Displays

100

As for virtual destructors, consistency with non-virtual ones and Quentin's answer are appropriate reasons. My personal advice is that you should always use the default when you can, as this is a way to stick to the most canonic behavior.

Upvotes: 1

Tony Delroy
Tony Delroy

Reputation: 106196

One use is making the destructor protected or private while potentially keeping the class trivial: just list it after the desired access specifier.

Another: when writing classes, some programmers like to order the class's functions: e.g. constructors, then the destructor, then the non-const "mutating" members, then the const "accessor" members, then static functions. By being able to explicitly = default the destructor, you can list it in the expected order and the reader looking there knows there can't be another misplaced version of it. In large classes, that may have some documentary/safety value.

It also gives you something concrete around which to add comments, which can help some documentation tools realise the comments relate to destruction.

Upvotes: 1

Quentin
Quentin

Reputation: 63144

The exception for trivial destructors omission has to do with the derived class' destructor, not the base one. So virtual ~Foo() = default; is a useful construct to keep the default destructor, but virtualize it.

Upvotes: 3

Dino
Dino

Reputation: 609

Basically it is about communicating the intent, but pretty redundant.

But in case you're using std::unique_ptr as a member of class you'll need to declare destructor (but only declare) in header. Then you can make it use default implementation in source file like so:

MyClass:~MyClass() = default;

Considering your options I would use first or third one.

Upvotes: 1

Related Questions