Animal ani = anim;
That creates a new object of type Animal
, regardless of the type of anim
. So ani.speak()
will call Animal::speak
, since that is the override for type Animal
.
If you were to create a reference (or pointer)
Animal & ani = anim;
then the dynamic type would be preserved, and T::speak
would be called. This is similar to what happens in Java when you copy an object reference; but you should not try to understand the C++ object model in terms of Java's since they are very different.
You can prevent accidental creation of base-class objects (sometimes known as "slicing", since it slices off the derived-class parts of an object) by making the base class abstract. That is, declare the function pure virtual, rather than non-pure with a default implementation:
virtual void speak() = 0; // Really not implemented
Abstract classes can't be instantiated as a complete object, so this will cause a compile-time error if you try to.