In addition to the destructor not being virtual, you are returning the address of a local variable. This is undefined behavior.
Mammal* MammalFactory(const std::type_info& ti)
{
if(ti == typeid(Dog))
{
cout << "running dog" << endl;
Dog D;
Mammal* dog = &D;
return dog; // so what happens to D when MammalFactory returns?
}
}
You make this same mistake for all the other derived classes. Once that function returns, there is no more "D". It has gone up into a puff of smoke, and you're returning the address of this variable that no longer exists.
Either create a new Mammal (return new Dog;
) or come up with a way to create a Dog and return one that isn't local (again, the issue isn't just with this class, but will all of our other classes).