Reputation: 31549
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
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
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
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
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