For which destructors are defaults used?
I can understand the default constructors, as user-defined constructors will disable compiler-generated objects that are not copyable, etc.
In the case of a destructor, besides changing the access category, what use is there for defining a default destructor, given that no user-defined member function can turn them off (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, default doesn't make them trivial, so what does that do well?
source to share
One use makes the destructor protected
or private
, at the same time, keeps the class trivial: just list it after the required access specifier.
Other: When writing classes, some programmers like to order class functions: eg. constructors, then destructor, then non-t22> "mutating" members, then const
"accessor" members , then static
. By being able to be explicitly a = default
destructor, you can list it in the order you expect, and the reader looking there knows there could be no other misplaced version. In large classrooms, this may have some documentary / safe value.
It also gives you something specific around which to add comments, which can help some documentation tools implement kill-related comments.
source to share
Basically we are talking about the transfer of intent, but rather redundant.
But if you are using std::unique_ptr
as a class member, you need to declare the destructor (but only declare) in the header. Then you can force it to use the default implementation in the source file like this:
MyClass:~MyClass() = default;
Given your options, I'll use the first or third.
source to share
As Nikos Athanasiou mentioned in a note , the default constructor makes the type trivially destructible where there is no user defined user. A little bit of code 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;
}
Display
100
As far as virtual destructors are concerned, consistency with non-virtual and Quentin are good reasons. My personal advice is that you should always use the default whenever you can, as this is the way to stick to most canonical actions.
source to share