Thomas Werner wrote:
> I created a CustomGrid with POL which views user data of different types.
> This grid's layout can be changed by the user, so (s)he can add or remove
> pre-defined columns (e.g. name, age, sex, city, date of birth... etc.).
> I'm going to add a couple of more column types. That means, that the
> structure which contains the data for one table row will be drastically
> increased and claims more memory even though one or more of its data
> members are not used.
>
> So I came up with the idea of a dynamic data structure which can hold a
> variable amount of "members" (CArray of pointers?) of different types.
> Unfortunately I'm stuck in implementing this. I tried several attempts
> and discarded them.
> I don't think that there's a container which can hold variables of
> different data types, so I'd appreciate any pointer to the right direction...
Well, C and C++ are statically-typed languages, so most containers
need to hold a value of a certain type.
The C++ way around this is to define a class and then have every
field type inherit from that class. Then you can store pointers
to the base class in the array and they *are* the same type,
because all instances of a subclass are also instances of the
base class (at least if you want to look at it that way).
The old-fashioned way of doing it is to use a union. Then, you
can do something like this:
typedef enum
{
ColTypeName, ColTypeAge, ColTypeSex, ColTypeCity
} ColType;
typedef Char *Name;
typedef Int16 Age;
typedef enum { Male, Female, UnknownSex } Sex;
typedef Char *City;
typedef struct
{
ColType coltype;
union
{
Name name;
Age age;
Sex sex;
City city;
};
} ColumnValue;
Then you can do stuff like this:
void SetDefaultColumnValue (ColumnValue *colval)
{
switch (colval->coltype)
{
case ColTypeName:
colval->name = NULL;
break;
case ColTypeAge:
colval->age = -1;
break;
case ColTypeSex:
colval->sex = UnknownSex;
break;
case ColTypeCity:
colval->city = NULL;
break;
}
}
The switches get old after a while.
One disadvantage of the union thing is that the union part
of the ColumnValue struct takes the size of the largest
one of its possible members. So if you made City an
array of 100 characters, then storing Age would take 100
characters as well. You can solve this, if you want, by
making all the members of the union pointers instead. But
then you've got to allocate dynamic memory for each one,
so that gets to be more of a pain.
Also, with all of this, writing to and from databases
gets to be a bit of a pain. But, there's not a ton
you can do about that. You just have to write the code.
With simpler data structures (without pointers) you can
just MemMove() or DmWrite() the whole struct into a
database, but that's error-prone (when you change the
struct in the future) and non-portable (b/c of different
endianness and structure packing) anyway, so the fact that
you lose that ability may be no big loss. Although it
does just about force you to do it correctly, which some
may regard as a disadvantage since doing things correctly
always takes a lot more time...
- Logan
--
For information on using the Palm Developer Forums, or to unsubscribe, please
see http://www.palmos.com/dev/support/forums/