Most of my code has been written in C, and like most old C
programmers I'm capable of writing C++ programs like I was writting in
C. I've decided to try to develope a modern C++ mindset, including
using things that weren't in the language when I bought and read the
C++ books that were lying around the house, for example, the STL.
So I've decided to use the STL containers in a current project
(basicly map or hash_map). They are pretty nifty. Since they own
the type they contain, it's destructor gets called for each member
when the container is destroyed, and that seems rightous and clean.
But what I'd like to contain is any one of a set of
polymorphic classes all derived from the same base class. They all
support the same interface, but their (per instance) size varies.
Since the base class is not the largest of them, you couldn't just
specify it as the contained type, since the container wouldn't provide
enough storage for the larger derived classes. Figuring out what
derived class is the largest, and using that as the contained type
might work, but strikes me as a hanging offense, even if one didn't
care about wasted storage.
One could contain pointers to the base class, and make do with
the extra "*" in the interface (or use the accursed preprocessor macro
facility). But then it is the pointer that is owned by the container,
and destroying it doesn't call the destructor for the class to which
it points. That means somehow hooking into the container's destructor
(and the only way that I know of to do that is to derive a class from
it) to loop accross the members and destroy them. That's not too bad,
but doesn't seem to be to really be in the C++ spirit.
Probably most tasty is a wrapper class containing a pointer to
the base class of the desired set of classes, and whose destructor
deletes the pointer's target. Since the wrapper isn't polymorphic and
contains only a pointer as a data member, its per instance size should
be the same as a pointer, so it doesn't waste any space when compared
to the pointer scheme.
But either its pointer is explicitly dereferenced everywhere
the target class's interface is used (not very C++), or it must have a
set of (inline) member functions that present the desired interface by
trivially encapsulating the pointer dereference. Notice that this
means that either the wrapper must also be derived from the common
base, or two instances of the interface must be maintained in parallel
(one in the base, one in the wrapper). Using the common base (which
is then an interface class at the ultimate root of the hierarchy), the
wrapping member functions can't be inlined and, worse, each call takes
an extra dereference through the wrapper's virtual function table.
Signing up to maintain two separate but identical interfaces,
again, does not seem to be the C++ way. Yes, the implementations
must track anyway, but if all the interface member functions are
pure virtual in the base class, the compiler will tell me if I
forgot to implement something in one of the derived classes.
Can anyone suggest a "fully correct" way to do this?
Bill
**********************************************************
To unsubscribe from this list, send mail to
[EMAIL PROTECTED] with the following text in the
*body* (*not* the subject line) of the letter:
unsubscribe gnhlug
**********************************************************