Destructor for class member `B`, why is it called in the below snippet?

From ยง5.3.5 [expr.delete] / 1 I can figure out that the destructor for the object is *a

shown in a snippet not shown below. But I didn't understand why the destructor for the class member is involved in this case B

, as 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 be grateful for a quote from the Standard explaining this.

+3


source to share


2 answers


Your delete *a

applies the operator delete

to an expression without a *a

type pointer A

. The only way it can be legal is when the type is A

implicitly convertible to some pointer type.

5.3.5 Delete [expr.delete]

1 ... The operand must have a pointer to an object type or a class type with one implicit conversion function (12.3.2) to a pointer to an object type.

2 If the operand is of class type, the operand is converted to a pointer type by calling the above conversion function, and the converted operand is used instead of the original operand for the rest of this section.

In this case, your class is A

implicitly converted to B *

, which is what happens when you do delete *a

.

In other words, yours is delete *a

actually being interpreted as

delete (*a).operator B*();

      



In your code, B

you are delete

, not A

. This is why the destructor is called B

.

If you want to destroy the object A

you will need to do

delete a;

      

(note, no *

). This will not call the destructor B

.

+13


source


if you tried to implement smart pointer - then you should probably look into the sources of boost

in a nutshell, the smart pointer pattern provides the idea of โ€‹โ€‹a small object that wraps the original object and destroys it as it is not needed.

for example a very simple example, also without custom deletes etc:



<template class T>
class scope_delete
{
 public:
   scope_delete(T* ptr) : p(ptr) {}
   ~scope_delete() { delete p; }
   T* operator->() { return p; }
 private:
   T * p;
};

// somewere in programm
{
  auto obj = scope_delete(new MyCLasss);
  obj->some_fun();
} // here stack object obj will be deleted and remove original object.

      

you should read some books for details, or I just google this article .

0


source







All Articles