Reputation: 42255
struct A1
{
~A1() {} // A1 is not trivially destructible
};
struct A2
{
~A2() = default; // A2 is trivially destructible
};
A2
is better than A1
, because A2
is trivially destructible while A1
isn't.
I think maybe we can safely say:
1. The user-defined empty destructor should never be used.
2. Any user-defined empty destructor should be replaced with the defaulted one.
Am I right?
Upvotes: 1
Views: 691
Reputation: 275385
In the header file:
struct some_secret_type;
struct some_public_type {
some_public_type();
~some_public_type();
private:
std::unique_ptr<some_secret_type> pImpl;
};
Then, in the cpp file:
#include <some_secret_type.h>
some_public_type::~some_public_type() = default;
some_public_type::~some_public_type() {};
Here I have explicitly declared a destructor that ended up being either empty or defaulted.
The effects of =default;
and {}
here are identical in the cpp file.
In the header file, having either a {}
or =default
would require everyone including it know what some_secret_type
looks like.
In a more general case, {}
and =default
in the header can change if a type is trivially destroyed. In the cpp/header split, they do not.
The advantage of {}
in the header is that you prevent a type from being trivial (suppose later you know you are going to make it non-trivial, and you don't want other behavior changes to happen when you do it).
In the cpp file case, {}
saves a few characters.
Upvotes: 2
Reputation: 2647
You can see a use case for such an empty destructor right there in your example. You can use it to force a trivial type to become non-trivial. That’s an outstandingly unlikely use case. But I wouldn’t be confident at all to call it never useful.
You’re not far off the mark, though. In a decade of programming C++ every day I’ve seen a lot of empty destructors, but not a single one that couldn’t be replaced with =default
or omitted entirely.
Still, I’d be wary of a mechanical replacement. So:
The user-defined empty destructor should almost never be used.
Almost every user-defined empty destructor should either be omitted entirely (preferred option) or replaced with the defaulted one.
Upvotes: 2