Your example appears to work, because there is no data, and no virtual methods, and no multiple inheritance. Try adding int value;
to derivedclass1
, const char *cstr;
to derivedclass2
, initialize these in corresponding constructors, and add printing these to corresponding show()
methods.
You will see how show()
will print garbage value (if you cast pointer to derivedclass1
when it is not) or crash (if you cast the pointer to derivedclass2
when class in fact is not of that type), or behave otherwise oddly.
C++ class member functions AKA methods are nothing more than functions, which take one hidden extra argument, this
pointer, and they assume that it points to an object of right type. So when you have an object of type derivedclass1
, but you cast a pointer to it to type derivedclass2
, then what happens without virtual methods is this:
- method of
derivedclass2
gets called, because well, you explicitly said "this is a pointer toderivedclass2
". - the method gets pointer to actual object,
this
. It thinks it points to actual instance ofderivedclass2
, which would have certain data members at certain offsets. - if the object actually is a
derivedclass1
, that memory contains something quite different. So if method thinks there is a char pointer, but in fact there isn't, then accessing the data it points to will probably access illegal address and crash.
If you instead use virtual methods, and have pointer to common base class, then when you call a method, compiler generates code to call the right method. It actually inserts code and data (using a table filled with virtual method pointers, usually called vtable, one per class, and pointer to it, one per object/instance) with which it knows to call the right method. So when ever you call a virtual method, it's not a direct call, but instead the object has extra pointer to the vtable of the real class, which tells what method should really be called for that object.
In summary, type casts are in no way an alternative to virtual methods. And, as a side note, every type cast is a place to ask "Why is this cast here? Is there some fundamental problem with this software, if it needs a cast here?". Legitimate use cases for type casts are quite rare indeed, especially with OOP objects. Also, never use C-style type casts with object pointers, use static_cast
and dynamic_cast
if you really need to cast.