There is one situation where the destructor will never be called, even for automatic variables: a destructor for anonymous union inside the class X
, when the user destructor X::~X
written by the user. Since the union is anonymous, there is simply no way that its destructor can be called X::~X
(now it’s not the same as calling the destructor because it does not know what to call the destructor).
By the way, in this situation, the user cannot declare the removal of the union destructor (again, due to the lack of a name), but it can be implicitly deleted.
Curiously, in this situation, the default destructor X::~X
would name the destructor for anonymous union. However, when allowed, this is a purely formal matter, and calling the destructor has no effect. This is due to the fact that this is allowed only if all union options have trivial destructors (and, therefore, the union itself); if any of them has a non-trivial destructor, the union destructor is implicitly deleted, which makes the default destructor X
inoperative (effectively deleted).
However, this does not mean that you cannot use class X
containing an anonymous union with at least one member with a non-trivial destructor. It simply means that the user-written X::~X
should directly destroy the active variant of the anonymous union, bypassing the remote destructor of the union itself. This is possible if the class contains additional elements that let you know which option is active. Similarly, X
constructors must directly build at most one join option, bypassing the (possibly remote) anonymous join constructor (unless the option is a POD, such a constructor should not directly assign the join option instead), In fact, the special member functions of the anonymous unions are a kind of phantom entities that cannot be nontrivial and whose only role, being possibly removed, is to effectively extend this remote status to the corresponding special nktsiyu member containing X
.
source share