views:

621

answers:

3

For example:

Base class header file has:

enum FOO
{
FOO_A,
FOO_B,
FOO_C,
FOO_USERSTART
};

Then the derived class has:

enum FOO
{
FOO_USERA=FOO_USERSTART
FOO_USERB,
FOO_USERC
};

Just to be clear on my usage it is for having an event handler where the base class has events and then derived classes can add events. The derived classes event handler would check for it's events and if the event was not for it, then it would pass the event down to the base class.

class Base
{
public:
    virtual void HandleFoo(FOO event);
};

class Derived: public Base
{
public:
    void HandleFoo(FOO event);
};


void Base::HandleFoo(FOO event)
{
     switch(event)
     {
     case FOO_A:
       /* do stuff */
     break;
     case FOO_B:
       /* do stuff */
     break;
     case FOO_B:
       /* do stuff */
     break;
     }
 }

void Derived::HandleFoo(FOO event)
{
     switch(event)
     {
     case FOO_USERA:
       /* do stuff */
     break;
     case FOO_USERB:
       /* do stuff */
     break;
     case FOO_USERB:
       /* do stuff */
     break;
     default:
          /* not my event, must be for someone else */
          Base::HandleFoo(event);
     break;
     }
 }
+2  A: 

Yes, as long as the enum's are both members of a class. If they weren't then they would be of the same type and the compiler would be very unhappy.

If the enums are in different classes, then how are they the same enum?
bk1e
True they aren't the same, but it depends on the behavior you are after. In the example above the two enums are technically different but having the same name in different classes might be enough for the purposes of the design. The poster did mention a base and derived class.
+1  A: 

No. The compiler needs to be able to decide whether the enum fits in a char, short, int or long once it sees the }.

So if the base class header has

enum Foo {
  A,
  B,
  MAX = 1<<15
};

a compiler may decide the enum fits in 16 bits. It can then use that, e.g. when laying out the base class. If you were later able to add 1<<31 to the enum, the base class enum member would not be able to hold one of the enum values.

MSalters
I know this is in the standard, but which compilers actually do this? I've tested GCC and it just uses 4 bytes for even the smallest values.
Same still holds in GCC for 32/64 instead of 16/32.
Steve Jessop
IBM's compiler, apparently (may depend on #pragma enum small / -qenum=small)
MSalters
A: 

Yes, this works. To simplify your code a bit, I would suggest this, more common method of "extending" enums:

enum FOO // Base class's FOO
{
FOO_A,
FOO_B,
FOO_C,
FOO_BASE_MAX // Always keep this as the last value in the base class
};

enum FOO // Derived class's FOO
{
FOO_USERA=FOO_BASE_MAX+1, // Always keep this as the first value in the derived class
FOO_USERB,
FOO_USERC
};

You still need to watch out for "out of order" enums. (Example: FOO_A=15, FOO_B=11, etc.)

Marcin
And for properly portable code, you can't always assign a Derived::FOO value to a Base::Foo variable, because the result of assigning an out-of-range value to an enum is undefined.
Steve Jessop