Path: utzoo!utgpu!attcan!uunet!wuarchive!psuvax1!gatech!mcnc!godot!sherouse
From: sherouse@godot.radonc.unc.edu (George W. Sherouse)
Newsgroups: comp.lang.c++
Subject: conceptual problem with related classes derived in parallel
Keywords: help, thanks
Message-ID: <1071@godot.radonc.unc.edu>
Date: 27 Sep 89 16:37:11 GMT
Organization: Radiation Oncology, NCMH/UNC, Chapel Hill
Lines: 81


Consider a class used for maintaining dynamically-allocated lists of
things.

class element
{
protected:
    data_type data;
public:
    virtual data_type data_accessor();
};

class list_of_elements
{
protected:
    element* list;
public:
    add_element_to_list(element);		<- uses malloc/realloc
};

Suppose then we derive a new class of element from element

class new_element: public element
{
protected:
    other_data_type other_data;
};

and a derived class of list_of_element to maintain the new elements

class list_of_new_element: public list_of_element
{
...
protected:
    new_element_manipulator();
};

Or, schematically:

	list         -- points to ->        element
         |                                     |
       derive                               derive
	 v                                     v
      new_list  -- would like to access -> new_element

The intent here is to reuse list maintenance code from the base
list_of_element class in the derived list_of_new_element class which
operates on the dervived data class new_element.  The scheme above
does not work because for either class of list this->list[n] is always
an instance of the base element class.  Without a cast,
new_list_manipulator will not be able to access other_data.
Similarly, add_element_to_list will not be able to divine the correct
size for the elements.

A number of solutions come to mind, but none particularly satisfying
from a philosophical point of view.

- casts would do the trick, but that would require that all of the
methods of list_of_elements be reimplemented for each derived class.

- one could leave the pointer to element out of the base class and
only introduce the pointer to derived classes of element at
appropriate levels in the list hierarchy.  This also requires
re-implementation of essentially identical list maintenance code in
derived classes.

- define the base class of element to have all possible values for all
possible derived classes of element.  Yuck.  This requires that the
base class be redefined in order to add new derived classes.

- give up and create a family of mostly-identical list classes that
share code by using non-method friend procedures - the moral
equivalent of goto.

This same problem in a number of different guises has cropped up in
different parts of a project we are working on.  Are we missing
something obvious here?  Are we missing something subtle?  It appears
that what we are really looking for is support for virtual data types.
Any help out there?

- George