From §5.3.5[expr.delete]/1, I can understand that the destructor for the object *a
is not invoked in the snippet below. But I didn't understand why is the destructor for the class member B
invoked in this case, as can be seen in this live example.
#include <iostream>
class A
{
public:
class B{ public: ~B(){ std::cout << "B dtor" << '\n'; } };
A() { p = new B(); }
operator B*() { return p; }
private:
B* p;
};
int main()
{
A* a = new A();
delete *a;
std::cout << "end" << '\n';
}
Would appreciate some quote from the Standard explaining this.
Your delete *a
applies operator delete
to a non-pointer expression *a
of type A
. The only way this can be legal is when type A
is implicitly convertible to some pointer type.
5.3.5 Delete [expr.delete]
1 ... The operand shall have a pointer to object type, or a class type having a single non-explicit conversion function (12.3.2) to a pointer to object type.
2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section.
In this case your class A
is implicitly convertible to B *
, which is exactly what happens when you do delete *a
.
In other words, your delete *a
is actually interpreted as
delete (*a).operator B*();
It is B
you delete
in your code, not A
. This is why the destructor of B
is called.
If you wanted to destroy the A
object, you'd have to do
delete a;
(note, no *
). That would not call B
's destructor.