devxlogo

Inheritance design

Inheritance design

Question:
Suppose I’ve got the following class hierarchies:

Surface_PlotContourSurface_Plot, child of Surface_PlotSurface_DataGridSurface_Data, child of Surface_DataSurface_Plot contains a Surface_Data object, ContourSurface_Plot contains a GridSurface_Data object
.What is the most elegant way to arrange the data members of the Surface_Plot hierarchy so that the Surface_Plot class can access the GridSurface_Data object’s Surface_Data behaviors, and ContourSurface_Plot can access its extended behaviors? My approach has been to make the xxxData objects pointers, and to have both a GridSurface_Data and Surface_Data pointer referencing the same data member.

This route to a solution seems terribly ugly and error-prone. Furthermore, my real hierarchies are much longer, resulting in a plethora of redundant pointers of increasingly sophisticated types.

There must be a cleaner way!

Answer:
You are right ? having two pointers is a problem and could end up becominga maintenance nightmare. The trick is to use the right type in the derived class to access the extended behavior. Consider:

class Surface_Plot{protected:   Surface_Data *data_;};class ContourSurface_Plot : public Surface_Plot{public:   void useExtendedOperation ()   {     GridSurface_Data * g = dynamic_cast(data);     if(g) g->doSomething ();   }};
That’s the basic idea. If the GridSurface_Data needs to be usedin a lot of places, it might be worthwhile to incorporate it asa data member and initialize it in the constructor of ContourSurface_Plot.This is similar to your multiple pointer solution. In this case you want to keep a reference in the derived class to prevent accidental deletion.

In an implementation I would move the burden of maintaining this extra pointer to another class that will do the cast, etc., as in:

template class Surface_Data_Container : public Surface_Plot{protected:   Surface_Data_Container() : data_(dynamic_cast(Surface_Plot::data_))   {      assert(data_ != 0);   }   T *data_;};
and then inherit ContourSurface_Plot from Surface_Data_Container:
class ContourSurface_Plot : public Surface_Data_Container{public:   void useExtendedOperation ()   {     data_->doSomething ();     // accesses Surface_Data_Container::data_ which is the    // right type..   }};

See also  Why ChatGPT Is So Important Today
devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist