Problem 1: object slicing
In your initialization
BaseClass foo = SubClass();
you create an anonymous temporary SubClass
object and copy-construct a BaseClass
object. This means that foo is and remains a BaseClass
that is copied from a SubClass
.
This is called object slicing. If the baseClass
would have data members, the corresponding data members of the subclass would be copied into it. If SubClass
would have additional data members, these would be lost.
If you want to work with BaseClass
objects, but without loosing the members of their real type, whether base or derived, you need to use reference or pointers:
BaseClass *foo = new SubClass; // foo is a base class pointer but points to a SubClass object.
SubClass bar;
BaseClass& foo2 = bar; // foo2 is a base class REFERENCE which refers to a Subclass object
But, this is not sufficient.
Problem 2: polymorphism
If you'd now calling the method:
foo->doSomething();
foo2.doSomething();
it would still be BaseClass::doSomething()
that would be called, despite the real type of the object pointed/referred to. That's because for normal member functions, the compiler tries to identify the function to call at compile time: and at compile it only knows the type of the pointer or reference.
To benefit from a polymorphic behavior, you also need to define the function as virtual
as explained by Johan. In this case, the compiler would generate code that with a little overhead is able to identify dynamically the type of the object and hence would call the correct version of the function exactly as you expect.
Note that if you have at least one virtual function in your base class, you'd better declare a virtual destructor for it.