0

mvce:

#include <memory>
#include <iostream>

using namespace std;

struct _A {
    ~_A() {
        cout << "~_A()" << endl;
    }
};

struct A : public _A {
    ~A() {
        cout << "~A()" << endl;
    }
};

int main(int argc, char** argv) {
    {
        shared_ptr<_A> p = make_shared<A>();
    } //~A() called

    return 0;
}

output:

~A()
~_A()

Here the destructors are not virtual but somehow the shared_ptr 'knows' it points to an A. Is this reliable or is this undefined behavior ? I want to know if it is necessary I flag the destructors with virtual in this case - assuming I don't work with raw ptrs.

PinkTurtle
  • 6,942
  • 3
  • 25
  • 44
  • what is the purpose of inheriting publicly if not for polymorphism? – 463035818_is_not_an_ai Mar 09 '20 at 15:15
  • 2
    Because you used `make_shared`, the shared ptr knows that `A` was constructed, even when it gets casted to a shared ptr to the superclass. Now, don't use `make_shared` to create the shared ptr, do `new A` yourself, assign it to `shared_ptr<_A>`, and watch the fireworks. – Sam Varshavchik Mar 09 '20 at 15:16
  • 2
    Side note: `_A` is an [illegal identifier](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). This code could result in utterly bizarre failure. – user4581301 Mar 09 '20 at 15:16
  • Destructor should be virtual. – KamilCuk Mar 09 '20 at 15:20
  • @user4581301 if illegal means it won't compile then it's not. Also do I risk jail ? – PinkTurtle Mar 09 '20 at 15:22
  • 1
    @PinkTurtle It's illegal in the sense that your program may fail to compile, it may fail to do what you want, or it might just "work". That's undefined behavior for you. – NathanOliver Mar 09 '20 at 15:24

0 Answers0