Tuesday, May 23, 2017

Four Solutions to Multiple Inheritance (Diamond Problem)

The Methods have been omitted for sake of convenience.
C++ Code
class point2 { private int x, y; };
class point3:point2 { private int z; };
class circle:point2 { private int r; };
class sphere:point3, circle { /*no new data*/ };

Solution 0: Diamond Problem is Intentional

C++ Code
class point2 { private int x, y; };
class point3: public point2 { private int z; };
class circle: public point2 { private int r; };
class sphere: public point3, circle { /*no new data*/ };

Solution 1: Data Synchronization -- A pain in the ass for compiler writers to implement. The compiler writer needs to have a data synchronization that synchronizes the same data inherited multiple times. This method is the hardest to implement; however, there is no need to change the current data structure. It has a keyword in C++ called "virtual".

C++ Code
class point2 { private int x, y; };
class point3: virtual point2 { private int z; };
class circle: virtual point2 { private int r; };
class sphere: virtual point3, circle { /*no new data*/ };

C Code for data
shallow view                                     deep view
struct point2 { int x, y; };
struct point3 { struct point2; int z; };         struct point3 { int x, y, z; };
struct circle { struct point2; int r; };         struct point3 { int x, y, r; };
struct sphere { struct point2; struct point3; }; struct sphere { int x, y, z, x, y, r; };

Solution 2: Composition is Inheritance -- Fold the data so that there is no multiple copies of any data. Function calls have multiple this pointers for each component that makes up the overall class. This solution will lead to stack overflow and also stackoverflow. There is no equivalent in C++.

C Code for data
shallow view                                     deep view
struct point2 { int x, y; };
struct point3 { struct point2; int z; };         struct point3 { int x, y, z; };
struct circle { struct point2; int r; };         struct point3 { int x, y, r; };
struct sphere { struct point2; struct point3; }; struct sphere { int x, y, z, r; };

Solution 3: Pointer Solution -- Use pointers to point to parent class data, then overlapping data would have pointers leading to the same data. Memory fragmentation is a pain. Use Solution 4 instead, unless proven that padded memory significantly takes more space.

C Code for data

struct point2 { int x, y; } spherePoint2;
struct point3 { struct point2* = &spherePoint2; int z; } spherePoint3;
struct circle { struct point2* = &spherePoint2; int r; } sphereCircle;
struct sphere { struct point2* = &spherePoint3; struct point3* = sphereCircle; };

Solution 4: De-Fragment Pointer Solution -- A De-fragment version of solution 3 by having the data internal to the structure on top of having pointers to parent class data.Remember that there is no "this" pointer in C, and C is not natively RAII. Resource Allocation and Resource Initialization are two separate steps in C, other than calloc() for simple structures. However, with a De-Fragment Pointer Solution, need to initialize those pointers properly. In C, there is variable declaration, resource allocation, and resource initialization. With a good constructor, RAII is possible, yet some compilers still complain uninitialized variable. Start with

struct ClassName * VariableName = NULL;
VariableName = new(VariableName, ClassType, ...(Initializers));

C Code for data
struct sphere
{
  struct point2 { int x, y; } spherePoint2; 
  struct point3 { struct point2* = &this.spherePoint2; int z; } spherePoint3; 
  struct circle { struct point2* = &this.spherePoint2; int r; } sphereCircle; 
  struct point2* = &this.spherePoint3; 
  struct point3* = &this.sphereCircle; 
};

Getting too many </code><code> got to get ride of them in HTML view and not Compose view.




No comments: