Consider the following snippet:
#include <memory>
#include <typeinfo>
#include <iostream>
class Widget {
};
int main() {
auto shared_ptr_to_widget = std::shared_ptr<Widget>({});
std::cout << "type of shared_ptr_to_widget: " << typeid(shared_ptr_to_widget).name() << std::endl;
auto maybe_a_widget = *shared_ptr_to_widget;
std::cout << "type of maybe_a_widget: " << typeid(maybe_a_widget).name() << std::endl;
}
This will output:
> type of shared_ptr_to_widget: St10shared_ptrI6WidgetE
> type of maybe_a_widget: 6Widget
However, if I replace the Widget class with:
class Widget {
public:
Widget(): a{1}{}
int a;
};
Then it seg faults at the following line:
auto maybe_a_widget = *shared_ptr_to_widget;
I understand if I actually wanted to make a shared pointer to an instance of an object I should use
std::make_shared<Widget>()
and this would actually call the constructor of Widget and everything would be fine and dandy. But I'd really like to understand what is going on here and why the behaviour changes based on the constructor of the Widget class.
I've tried looking at the constructors for shared_ptr http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr but I get a bit lost. I imagine it's my lack of understanding in what is actually happening when using an empty initializer list as a parameter to shared_ptr<>().