home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!cis.ohio-state.edu!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!eff!news.byu.edu!ux1!fcom.cc.utah.edu!swillden
- From: swillden@news.ccutah.edu (Shawn Willden)
- Subject: Re: Getting type info back !
- Message-ID: <1992Sep1.150027.26050@fcom.cc.utah.edu>
- Sender: news@fcom.cc.utah.edu
- Organization: University of Utah Computer Center
- X-Newsreader: Tin 1.1 PL3
- References: <YeckhJS00awJ0JJJV7@andrew.cmu.edu>
- Date: Tue, 1 Sep 92 15:00:27 GMT
- Lines: 71
-
- 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
-