0

Consider abstract class AbstractMap and it's child classMyMap. Is it safe to perform the following delete operation? Or, should I delete the ptr only after re-casting to MyMap? And why? I guess it is unsafe, because in this case destructor of MyMap is not called.

AbstractMap* ptr;
ptr = static_cast<AbstractMap*>(new MyMap());
delete ptr;

The past question talked about casting to void* case, but I'm not sure for my case.

orematasaburo
  • 1,207
  • 10
  • 20
  • 2
    It will depend on whether `AbstractMap` is ready for polymorphism. (i.e. whether its destructor is marked as virtual) – MikeCAT Jun 18 '21 at 14:49
  • 4
    It is allowed **only if** `AbstractMap` has a virtual destructor. If it doesn't, the behavior of the program is undefined. – Pete Becker Jun 18 '21 at 14:49
  • 5
    The static_cast is not needed in the described case. – 273K Jun 18 '21 at 14:50
  • @PeteBecker thanks! Suppoes `AbstractMap` has a virtual destructor, how can it call the child class's destructor? I mean, say we have other many child classes of `AbstractMap`, how can it know that the "original" one is `MyMap`? – orematasaburo Jun 18 '21 at 14:55
  • It doesn't have to do anything. `delete ptr;` will do the right thing: it will call the derived destructor, The derived destructor will do whatever it needs to do, then call the base destructor. – Pete Becker Jun 18 '21 at 14:57
  • 1
    That's the magic of `virtual`. The correct version of the function is called in all cases. Behind the scenes this is typically implemented with [a "vtable"](https://en.wikipedia.org/wiki/Virtual_method_table). – user4581301 Jun 18 '21 at 15:08

2 Answers2

2

Provided that AbstractMap's (or it's base if any) destructor is marked as virtual, delete ptr would be well-defined.

Compiler will invoke the most derived destructor virtually (as with any virtual function), which will, in turn, call destructor(s) of base(s) non-virtually.

A destructor will have all necessary code to call destructors of all member objects, and in the end of this process the memory will be reclaimed back to heap manager (based on size of allocated block).

SergeyA
  • 61,605
  • 5
  • 78
  • 137
2

Consider abstract class AbstractMap and it's child classMyMap. Is it safe to perform the following delete operation?

ptr = static_cast<AbstractMap*>(new MyMap());
delete ptr;

Deleting through a pointer to base sub object can be safe only if the destructor of the base (AbstractMap in this case) is virtual. If that precondition isn't satisfied, then the behaviour of the program is undefined.

Suppoes AbstractMap has a virtual destructor, how can it call the child class's destructor?

Note that if you created the instance using allocating new expression, then you aren't supposed to call the destructor directly. delete will do that for you.

But in the special cases where you may need to call the destructor directly, you do it by calling the destructor of AbstractMap using dynamic dispatch (which is the default form of dispatch for virtual functions).

how can it know that the "original" one is MyMap?

You don't need to know the dynamic type. That's what makes virtual functions so great.


P.S. Avoid owning bare pointers. There's hardly ever a need to write new and delete.

eerorika
  • 232,697
  • 12
  • 197
  • 326