Sunday, February 17, 2008

Inheritence and Casting

In order to go through inheritence and casting, I will use the following classes:


It is possible to create 2 objects of these classes like so:


You can view these classes like in the diagram below with the base object on the left and the derived object on the right. The derived class can be viewed as a base class with the additional member variables/functions of the derived class (of course it cannot access the private member variables of the base class object within it, but they do exist in memory).


All is well and good so far. Lovely jubbly. So now we want to copy the objects. We can either copy the baseObject to the derivedObject or vice versa. One which is fine, but the other is not.

Why is this so. Well, if you have a derivedObject and want to convert it to a baseObject, you can just strip away the extra functionality from the derived class and you are left with a base object.The value of baseMember will be of that created in derivedObject, i.e. 222.

We cannot go in reverse though as if we want to create a derived object from a base object, where is the extra derived functionality going to come from?? All we have is a plain old base object, not a derivedMember in sight....

Ok, hopefully that is nice and clear. Now if we want to create pointers that point to these objects we can do the following:


This is obviously ok, and can be viewed as such:


pBaseObject expects to point to an object of size BaseClass, and pDerivedObject expects to point to an object of size DerivedClass and whaddaya know, both of them are. All is well.

So now, lets do something crazy and switch the pointers around. Point pBaseObject to derivedObject and pDerivedObject to baseObject. Again, only one of these is ok to do, and the other will result in an error. Pointing pBaseObject to derivedObject is ok as derivedObject also contains a baseObject, so when the BaseClass pointer points to it, it can just point to the BaseClass object contained within it (as on the left in the picture below).

However, you cannot do the oppossite. If pDerivedObject tries to point to a BaseClass object it expects to point to something of size DerivedClass. Where is all of the extra derived functionality going to come from?? You cannot call setDerivedMember() because it does not exist for that object. This will result in an error.



The big difference between casting between pointers and copying between objects is that when you copy a derived object to a base one, all of the derived functionality gets sliced off and all that is left is the BaseClass object. When you point a BaseClass pointer to a DerivedClass object the entire DerivedClass object remains, you can point a different pointer to a DerivedClass back to it and it will still contain all of the functionality/member values.

So, in above, pDerivedObject2 points to the origional object with the derived class functionality intact (i.e. a derivedMember and baseMember value of 222).

The rules for casting with references is the same as for casting real objects (after all, references are just another name for the objects), Thus you can assign a BaseClass reference to a DerivedClass object, but you cannot go vice versa. Note however, that assignment in this way will not 'slice' the derived object and all of the settings/functionality of it will remain intact.


That's all for now, hope you like the pictures, they took ages!!!

--
Lurning Man
--

No comments: