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..   }};

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: