Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

Tip of the Day
Language: Design Patterns
Expertise: Beginner
Jul 18, 1997

Inheritance design

Suppose I've got the following class hierarchies:
ContourSurface_Plot, child of Surface_Plot

GridSurface_Data, child of Surface_Data

Surface_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!

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

class Surface_Plot
   Surface_Data *data_;

class ContourSurface_Plot : public Surface_Plot
   void useExtendedOperation ()
     GridSurface_Data * g = dynamic_cast(data);
     if(g) g->doSomething ();
That's the basic idea. If the GridSurface_Data needs to be used in a lot of places, it might be worthwhile to incorporate it as a 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:

class Surface_Data_Container : public Surface_Plot
   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
   void useExtendedOperation ()
     data_->doSomething (); 
    // accesses Surface_Data_Container::data_ which is the
    // right type..
DevX Pro
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date