Search code examples
c++language-lawyerc++14delete-operator

The destructor for the class member `B`, why is it invoked in the snippet below?


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.


Solution

  • 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.