Better way to do this? (enum or map?)

M

MathStuf

I am creating a program that uses a lot of enumerations and associated
arrays of strings that look like this:

enum Enum1
{
E1_NONE = -1,
E1_A = 0,
E1_B = 1,
E1_END = 2
}
const string Enum1Str[E1_END]={"Val 1","Val 2"};

I was thinking about creating a derived map<string, int> class to
handle this better, but if I were to do so, I would need the following
methods added to it (though I'm not 100% familiar with iterators, so
the return values for KeyList and ValueList may not be correct):

vector<string>::iterator KeyList();
vector<int>::iterator ValueList();
string KeyOf(int val);

I think if I all I had were simple enumerations such as the one above,
the derived class would be overwhelmingly preferable, but I also have
enumerations as such:

enum Enum2
{
E2_NONE = -1,
E2_A = 0,
E2_B = 1,
E2_C = 2,
E2_D = 3,
// One possibility
E2_E = 4,
E2_END_1 = 5,
// Fork off different options
E2_F = 4,
E2_G = 5,
E2_END_2 = 6,
}
const string Enum2Str1[E2_END_1]={"Ref 1","Ref 2","Ref 3","Ref 4","Ref
5A"};
const string Enum2Str2[E2_END_2]={"Ref 1","Ref 2","Ref 3","Ref 4","Ref
5B","Ref 6B"};

which are there for double duty because sometimes values overlap when
different options are set.

Would it be in my best interest to go with the class and split up the
dual-duty enumerations or find some way to extend the class even
further to allow for multiple "ends" of the allowable options? If that
would be that case, how exactly might I go about doing that? Thanks in
advance.

--MathStuf
 
A

Alf P. Steinbach

* MathStuf:
I am creating a program that uses a lot of enumerations and associated
arrays of strings

Consider whether you can replace enums with types.

E.g., instead of

enum Kind{ a, b, c };

struct Something { Kind kind; ... };

void foo( Something& x }
{
switch( x.kind )
{
case a: doA( x ); break;
case b: doB( x ); break;
case c: doC( x ); break;
}
}

int main()
{
Something sth;
sth.kind = c;
foo( sth );
}

try

struct Something
{
...
virtual void foo() = 0;
};

struct A: Something { void foo() { /* like doA */ } };
struct B: Something { void foo() { /* like doB */ } };
struct C: Something { void foo() { /* like doC */ } };

int main()
{
C sth;
sth.foo();
}
 
J

John Harrison

MathStuf said:
I am creating a program that uses a lot of enumerations and associated
arrays of strings that look like this:

enum Enum1
{
E1_NONE = -1,
E1_A = 0,
E1_B = 1,
E1_END = 2
}
const string Enum1Str[E1_END]={"Val 1","Val 2"};

I was thinking about creating a derived map<string, int> class to
handle this better, but if I were to do so, I would need the following
methods added to it (though I'm not 100% familiar with iterators, so
the return values for KeyList and ValueList may not be correct):

Derivation is not a good idea for this case. You should write a class
that contains a map as a data member, and expose just the methods you
need instead of thinking in terms of adding to the existing map iterface
(most of which you won't need, some of which would probably actually be
harmful).
vector<string>::iterator KeyList();
vector<int>::iterator ValueList();
string KeyOf(int val);

KeyList and ValueList are not natural fits with a map. If you really
need these you would have to store seperate data member to perform
implement this. So you class would hold a map, plus two vectors. In fact
it would problably be simpler to drop the map and store two vectors,
with the key list vector being sorted for fast access. I'm assuming here
that once an enumeration class has been initialised you wouldn't need to
change it thereafter.
I think if I all I had were simple enumerations such as the one above,
the derived class would be overwhelmingly preferable, but I also have
enumerations as such:

enum Enum2
{
E2_NONE = -1,
E2_A = 0,
E2_B = 1,
E2_C = 2,
E2_D = 3,
// One possibility
E2_E = 4,
E2_END_1 = 5,
// Fork off different options
E2_F = 4,
E2_G = 5,
E2_END_2 = 6,
}
const string Enum2Str1[E2_END_1]={"Ref 1","Ref 2","Ref 3","Ref 4","Ref
5A"};
const string Enum2Str2[E2_END_2]={"Ref 1","Ref 2","Ref 3","Ref 4","Ref
5B","Ref 6B"};

which are there for double duty because sometimes values overlap when
different options are set.

Would it be in my best interest to go with the class and split up the
dual-duty enumerations or find some way to extend the class even
further to allow for multiple "ends" of the allowable options? If that
would be that case, how exactly might I go about doing that? Thanks in
advance.

I really think you have to stop thinking in terms of derivation (or
extension) as means of solving these problems. Instead think of one or
more classes containing whatever appropriate data structures you need.
--MathStuf

john
 
M

MathStuf

MathStufwrote:
I am creating a program that uses a lot of enumerations and associated
arrays of strings that look like this:
enum Enum1
{
E1_NONE = -1,
E1_A = 0,
E1_B = 1,
E1_END = 2
}
const string Enum1Str[E1_END]={"Val 1","Val 2"};
I was thinking about creating a derived map<string, int> class to
handle this better, but if I were to do so, I would need the following
methods added to it (though I'm not 100% familiar with iterators, so
the return values for KeyList and ValueList may not be correct):

Derivation is not a good idea for this case. You should write a class
that contains a map as a data member, and expose just the methods you
need instead of thinking in terms of adding to the existing map iterface
(most of which you won't need, some of which would probably actually be
harmful).


vector<string>::iterator KeyList();
vector<int>::iterator ValueList();
string KeyOf(int val);

KeyList and ValueList are not natural fits with a map. If you really
need these you would have to store seperate data member to perform
implement this. So you class would hold a map, plus two vectors. In fact
it would problably be simpler to drop the map and store two vectors,
with the key list vector being sorted for fast access. I'm assuming here
that once an enumeration class has been initialised you wouldn't need to
change it thereafter.




I think if I all I had were simple enumerations such as the one above,
the derived class would be overwhelmingly preferable, but I also have
enumerations as such:
enum Enum2
{
E2_NONE = -1,
E2_A = 0,
E2_B = 1,
E2_C = 2,
E2_D = 3,
// One possibility
E2_E = 4,
E2_END_1 = 5,
// Fork off different options
E2_F = 4,
E2_G = 5,
E2_END_2 = 6,
}
const string Enum2Str1[E2_END_1]={"Ref 1","Ref 2","Ref 3","Ref 4","Ref
5A"};
const string Enum2Str2[E2_END_2]={"Ref 1","Ref 2","Ref 3","Ref 4","Ref
5B","Ref 6B"};
which are there for double duty because sometimes values overlap when
different options are set.
Would it be in my best interest to go with the class and split up the
dual-duty enumerations or find some way to extend the class even
further to allow for multiple "ends" of the allowable options? If that
would be that case, how exactly might I go about doing that? Thanks in
advance.

I really think you have to stop thinking in terms of derivation (or
extension) as means of solving these problems. Instead think of one or
more classes containing whatever appropriate data structures you need.


--MathStuf

john

Thanks for the help. I have decided to go with a class with two
vector, one for keys, the other values and allow the subscript
operator to be used both ways.

--MathStuf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top