0

Is it possible to delete a derived class object stored in a base class object when the base class has no virtual destructor?

BaseClass *obj = new DerivedClass();
delete obj;

The above piece of code throws a warning, which says:

delete called on object which is abstract but has non-virtual destructor

Is it possible to cast the object to a derived class object? Something like this:

delete dynamic_cast<DerivedClass *>(obj);

Will this work? If not, is there a viable way to achieve this without adding a virtual constructor?

mtm
  • 504
  • 1
  • 7
  • 25
  • Without a virtual destructor, `dynamic_cast` has no effect. Just add the virtual destructor to `Base`, or give up on inheritance and add a data member of type `Base` to `Derived`. – Spencer Sep 19 '22 at 13:13
  • Add a virtual destructor. If your class is polymorphic, this is a requirement. – NathanOliver Sep 19 '22 at 13:14
  • 1
    @Spencer dynamic_cast requires one virtual function, it doesn't have to be the destructor. – john Sep 19 '22 at 13:15
  • I guess: https://godbolt.org/z/rd14zee5W ; But you still need at least 1 virtual function for `dynamic_cast` to work, so you can as well just provide the virtual destructor. If you can't, don't derive from this class. – pptaszni Sep 19 '22 at 13:17
  • 3
    If you are certain `obj` really does point to `DerivedClass` then you can static cast it, `delete static_cast(obj);`. But the real question is, why not just add a virtual destructor to `BaseClass`. – john Sep 19 '22 at 13:17
  • Since `BaseClass` seems to be an abstract class it has at least one virtual function, so that dynamic cast will get you a valid pointer to `DerivedClass`. So you have a valid workaround for the underlying design error. – Pete Becker Sep 19 '22 at 13:17
  • @john It's also pointless to leave out the virtual destructor if a class has other virtual functions.. It's also a form of self-harm. – Spencer Sep 19 '22 at 13:18
  • @Spencer Well that's the strange thing, the OP hasn't said why they can't add a virtual destructor. Unless there is some unbreakable reason adding a virtual destructor is what they should do. – john Sep 19 '22 at 13:19
  • @Spencer — a virtual destructor is required **if** the design calls for deleting objects of derived types through pointers to the base type. There are valid designs that do not require that. – Pete Becker Sep 19 '22 at 13:21
  • @PeteBecker It may not be required, but you gain nothing by leaving it out, if there are other virtual functions. – Spencer Sep 19 '22 at 13:25
  • 1
    If the Base class ought not be able to be used to `delete` derived classes, make the destructor `protected:` (I'd also make it `virtual`, but only to shut up my compiler's warnings). See Herb Sutter's [guideline #4](http://www.gotw.ca/publications/mill18.htm). – Eljay Sep 19 '22 at 13:29
  • Does this answer your question? [Downcasting using the 'static\_cast' in C++](https://stackoverflow.com/questions/6322949/downcasting-using-the-static-cast-in-c) – Spencer Sep 19 '22 at 13:37
  • @john It's an assignment question and we were asked not to make any changes to the abstract class. Hence the search for a workaround. – mtm Sep 19 '22 at 15:52
  • @MathewThomas Badly set question then, probably just an oversight, as said above there is absolutely no reason not to have a virtual destructor in an abstract class. – john Sep 19 '22 at 18:45
  • @john The only reason I can think of is that you're stuck with preserving the ABI of someone else's library. – Spencer Sep 19 '22 at 19:17

0 Answers0