From: swillden@news.ccutah.edu (Shawn Willden)
Subject: Re: Getting type info back !
Organization: University of Utah Computer Center
X-Newsreader: Tin 1.1 PL3
Date: Tue, 1 Sep 92 15:00:27 GMT

sm86+@andrew.cmu.edu (Stefan Monnier) writes:
: 
: I would like to store different type of objects in a 'generic' structure,
: using the (void *)
: The problem I'm faced with is that of determining the real type of an 
: object after storing in that structure (when I take it back)
: 
: It is a quite general question.

[ Description of question and Eiffel support deleted ]

Putting aside for the moment the question of whether or not you should want
to create heterogeneous collections (I try very hard to avoid them), what you
want can be done, but you have to do some work.  The problem is that C++ 
doesn't (currently) provide any type of run-time type information (RTTI) so
you must provide it yourself if you need it.  Here are a couple of the most
common ways to handle this problem:

	1)  Derive all classes you want to be able to place in your structure
	from a common base class, I'll call it Generic.  This base class
	should have a pure virtual method that descendants will override to
	provide type information (e.g. an integer that uniquely specifies
	the class).  If you want to be able to use sorted data structures
	you should also provide a pure virtual function lessThan (or some-
	thing to that effect).  Then, instead of handling void*'s in your
	structure, work with Generic*'s.  Then you can do something like:

	void foo(SomeDataStructure& data)
		{
		Generic* found;
		MyClass myObject;	// Suppose MyClass is descended from
					// Generic.
		found = data.getItem();
		if (found->classType() == myObject.classType())
			myObject = *found;
		// ...
		}
	2)  If you *really* want to work with void*'s you can place your
	void* in a struct along with some type information.  Every time you
	add an object to your data structure you will have to pass both the
	pointer to the object and the type information to the structure which
	must store them together.  Then, when you retrieve the object, you
	also must get the type info and use a switch to do the appropriate 
	cast.  This allows you to avoid mucking with your inheritance 
	hierarchy but is extremely easy to mess up.  Mistakes can be disastrous
	and extremely hard to find.

There are many other ways of doing this but they all boil down to:

	C++ does *not* provide RTTI.  If you want it you must provide
	it yourself.

In general, I prefer to use the 1st method I mentioned when I have to have 
heterogeneous collections.  If at *all* possible I use class templates for
my generic structures and make homogeneous collections.  If I find myself
wanting to place very different types of objects in the same pile I step 
back and ask myself why I want to do that and whether or not those objects
really have anything in common.  99% of the time there is a better way.
(Things like OODBMSs and class browsers are examples of things in the other
1% - they do exist but they are rare.)

: 
: -----------------------------------------------------
: -- On the average, people seem to be acting normal --
: -----------------------------------------------------

On the average, most people normally do.

--
Shawn Willden
swillden@icarus.weber.edu
Newsgroups: comp.lang.c++