Resetting to null isn't sufficient; the implementations of
std::shared_ptr
I know also have a pointer to the reference
count, which must be deleted as well.
You need to keep track of what is currently in the union, and use explicit calls to the destructor and placement new for construction any time the type changes (and in the constructors and the destructor).