Further extending the inheritance hierarchy mentioned in part -1, consider that now the company has decided to introduce an open source mobile OS, based on existing "Mobile_OS" of the company but enhancing it further to favor open source development with a strong eco-system of contributors and names it "Android".
The
memory layout of Android class will be exactly same as of "WindowsPhone" class mentioned earlier, since both of these two classes are derived from the same base "Mobile_OS"
The design looks good till this point, with reusable modules and well defined class hierarchy. Now consider, the same company which had produced Windows and Android phones has now plans to come up with "Tablet" devices, with a hybrid operating system, based on superior features of both windows and android phones and making itself a unique OS by adding exclusive unique features and calls it " Hybrid_Tablet "
Do you foresee any problems with this design ?
Yes, we run into issues of data redundancy and inconsistency by deriving a " Hybrid_Tablet " from " WindowsPhone" and "Android" classes.
What caused issues of data redundancy and inconsistency ?
The cause of these issues is rooted in the fact that, both "WindowsPhone" and "Android" classes are derived from a common base "Mobile_OS" and hence both of these two classes persist its own instance of "Mobile_OS" class leading to issues of data redundancy and inconsistency.
How expensive is this fault ?
It depends on size of the base class, in our case it is the size of "Mobile_OS" class. Even if the developer cautiously resolves issues of data inconsistency by object reference for class data access, there is no solution to curb data redundancy. And if the base class is huge with many data members this design decision proves expensive.
What is the solution ?
The only solution to problems like above is to use Virtual Inheritance.
In a system of classes, belonging to a single hierarchy, if a class is derived from multiple base classes which are in-turn derived from a single base class, the concept of Virtual Inheritance is used to ensure that there is only a single copy of the common base class in the most derived class.
Deploying virtual inheritance in the current issue, we can ensure that the "Hybrid_Tablet" will have only a single instance of "Mobile_OS" which is commonly shared between "WindowsPhone" and "Android".
To inform the compiler to use single instance of "Mobile_OS" in " Hybrid_Tablet" the two base classes of " Hybrid_Tablet" which are "WindowsPhone" and "Android" should be derived virtually from "Mobile_OS" as shown below.
class Mobile_OS
{
public:
float iKernalVersion;
float iReleaseVersion;
char* strVendor ;
virtual float GetKernalVersion();
virtual float GetReleaseVerison();
Mobile_OS();
~ Mobile_OS();
};
class WindowsPhone : public virtual Mobile_OS
{
private:
char* strCodeName ;
char* iHardwarePlatform ;
public:
int iCustomRomVersion ;
float GetKernalVersion();
float GetReleaseVerison();
WindowsPhone();
~ WindowsPhone();
};
class Android : public virtual Mobile_OS
{
private:
char* strVendor;
char* strProjectCode ;
public:
int iAndroidCustomRomVersion ;
float GetKernalVersion();
float GetReleaseVerison();
Android ();
~ Android ();
};
Memory Layout of an object in case of Virtual Inheritance
In the case of non virtual inheritance, it is most certainly accepted design practice that both base class and derived class will have the same starting address since in a derived class the base instance is placed first. For more details please refer
Part -1
In the case of virtual inheritance, embedded base virtually floats within the derived object without having a definite fixed displacement. Hence there is an overhead of maintaining this information within the derived virtual object. and this is achieved by maintaining "Virtual Base Table Pointer" and "Virtual Base Pointer Table" as shown in the diagram below.
|
Click on the image for high resolution version |
The instance of each virtually derived class will have a hidden pointer "vbptr" which is an acronym for " Virtual Base Table Pointer" which points to "Virtual Base Pointers Table" of a class. The Virtual Base Pointers Table contains displacement of the virtual base within the derived class from the address point of "vbptr" in number of bytes.
In the above example "Android::vbptr" points to "Virtual Base Pointers Table" which has two entries. which are displacement values for virtual base, and the acronyms stand for,
And_Dt_And_vbptr_And = In Android Instance Distance of Android vbptr to Android
And_Dt_And_vbptr_Mos = In Android Instance Distance of Android vbptr to Mobile_OS
Memory Layout of Most Derived class in virtual inheritance.
Now, coming back to our original issue of designing a " Hybrid_Tablet" by deriving from multiple base classes which are derived from common base class, can be addressed using virtual inheritance. And this is achieved by,
1) Deriving "WindowsPhone" and "Android" virtually from "Mobile_OS", and
2) Deriving " Hybrid_Tablet" from "WindowsPhone" and "Mobile_OS".
class Hybrid_Tablet : public WindowsPhone, public Android
{
Private:
..................
..................
public:
..................
..................
};
|
Click on the image for high resolution version |
Hbt_Dt_Wnp_vbptr_Wnp = In Hybrid_Tablet Instance Distance of WindowsPhone to WindowsPhone
Hbt_Dt_Wnp_vbptr_Mos = In Hybrid_Tablet Instance Distance of WindowsPhone to Mobile_OS
Hbt_Dt_And_vbptr_And = In Hybrid_Tablet Instance Distance of Android to Android
Hbt_Dt_And_vbptr_Mos = In Hybrid_Tablet Instance Distance of Android to Mobile_OS
With this, I hope this article delineates moderately deeper insight of virtual inheritance and its implementation details. Kindly mail me if you have any queries or suggestions.
Also, please let me know if you are further interested in digging deeper into virtual inheritance in understanding "Data Access" and "Function Calling" mechanisms, I can write a post on that as well.
E- Mail : mail2vijaydr@gmail.com
References : MSDN, CodeProject, CodeGuru, and other web resources.