2

Let's consider the following code:

#include <iostream>

struct A{ virtual void foo(){ } };

struct B : A { virtual void foo(){ } };

A *a = new B;


int main()
{
    delete a; //UB?
}

I deliberately didn't define a virtual destructor. The compiler printed a message about causing UB, is it true?

1 Answers1

5

Formally you have UB if you delete through a pointer to T, which is not the most derived type, and T doesn't have a virtual destructor.

In practice you can get away with it if you don't have any data mambers, but it's still very ungood and unnecessary practice.

Note: when you use a shared_ptr it creates a deleter function at the point of initialization, and that deleter function can remember the original type, which, if that type is the most derived type, ensures well-defined deletion. E.g. in your case shared_ptr<A> p( new B ); would be OK.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 2
    Personally, I don't think it's good practice to rely on this capability of `std::shared_ptr`. – Lingxi Apr 25 '15 at 06:23
  • Nice, distinction about the `shared_ptr` I hadn't thought of that. – Stian Svedenborg Apr 25 '15 at 06:23
  • To me, this behavior of `std::shared_ptr` is more of a side-effect rather than by intention. – Lingxi Apr 25 '15 at 06:26
  • @Lingxi: The single pointer argument constructor is templated only in order to support this functionality. Without giving this support, it would not need to be templated. So it's very much by design: there is a templating just for this purpose. – Cheers and hth. - Alf Apr 25 '15 at 06:55