Consider the code below:
#include <iostream>
#include <memory>
struct Base
{
~Base() {std::cout << "~Base()" << std::endl;}
};
struct Derived : Base
{
~Derived() {std::cout << "~Derived()" << std::endl;}
};
int main()
{
// why does the right destructor is called at program exit?
std::shared_ptr<Base> sptrBase{std::make_shared<Derived>()};
}
which outputs
~Derived()
~Base()
My Base class doesn't have a virtual destructor. However, when using a Derived object via a smart pointer to Base, the correct ~Derived() destructor seems to be correctly invoked at program exit. Why does this happen (instead of undefined behaviour)? Is it because the Derived type is somehow "recorded" when the result of std::make_shared<Derived>() is converted into std::shared_ptr<Base>? Or is it plain UB?