Tuesday, August 23, 2005

Storing objects in a union

I am writing a nested table structure to mimic data returned from a
database (actually, a heirarchical recordset).

I am representing the cells where the actual data is stored, by a union:

class Cell {
union {
char* s ; //std::string s ;
long l ;
double d ;
void *t ;//Table* t ;
}cell ;

......

};

I know objects (with a copy constructor) cannot be stored directly in a
union (anyone knows the *technical* reasons why?). I am "hacking" around
this by storing a pointer to the object instead - is there anything I am
overlooking (i.e. is this dangerous?, any gotcha's I should be aware
of?) - if yes, I would appreciate an alternative solution to allow me to
stor objects (or their pointers) in a union.
- Ann Huxtable

3 Comments:

At 5:42 PM, August 23, 2005, Anonymous Anonymous said...

An object with any kind of non-trivial initialization or destruction
can't be stored in a union. That includes objects with ANY kind of
constructor, objects with members with constructors, objects with
destructors, or objects that contain virtual functions. These require
the object to be constructed using a constructor, which does extra
stuff behind the scenes. It is assumed that that extra stuff is
required and can't be skipped. If you have more than one object with
non-trivial initialization in the union, who's constructor should be
called? How does an object know whether or not its destructor should
be called? etc.

Using a union to store data often isn't the best idea. Ideally, you'd
have ONE data type (perhaps std::string) to represent all the different
kinds of data, then do conversions between std::string and int, or what
else, as needed.

Another solution would be to use polymorphism. Have a generic object
base class, then derive a stringObject, intObject, etc from it.
However, then you have the problem: how do you get at the data and how
do you know what kind of data you have? Well, then you introduce
dynamic_cast, which probably isn't the most elegant solution.

There's also boost::any, (www.boost.org) which is similar to the second
solution.

 
At 5:43 PM, August 23, 2005, Anonymous Anonymous said...

On the same Boost site, there is a library for a variant type which
would probably be better suited for this kind of problem. The Boost
variant library uses templates and compile-time type transformations --
a technique that minimizes runtime overhead while providing a greater
margin of safety than a solution that relied on identifying dynamic
types.

 
At 5:44 PM, August 23, 2005, Anonymous Anonymous said...

> On the same Boost site, there is a library for a variant type which
> would probably be better suited for this kind of problem.

Have you actually used it or is that just a conjecture?

 

Post a Comment

<< Home