Click here to Skip to main content
12,394,788 members (71,529 online)
Click here to Skip to main content
Add your own
alternative version

Stats

83.9K views
35 bookmarked
Posted

Inheriting a C++ enum type

, 29 Oct 2006
Rate this:
Please Sign up or sign in to vote.
Allow a C++ enum type to be extended unambigously.

The Problem

C++ does not have a facility to allow one enum type to be extended by inheritance as it does for classes and structures. Sometimes it is important to have this functionality. Suppose you had:

// in Fruit.h
enum Fruit { Orange, Mango, Banana };
// in eat.h
#include "Fruit.h"
void eat(Fruit fruit);

If you wanted to add another fruit type, you could extend Fruit as follows:

enum Fruit { Orange, Mango, Banana, Apple, Pear };

You could also have another function that handles the extra fruit:

void consume(Fruit fruit);

There are two problems with this approach:

  1. Fruit.h may be a library file that you don't necessarily want to change.
  2. void eat(Fruit) is implemented in some library that you can't change and as a result it might not handle 'Apple' properly but will still compile without errors. Your consume(Fruit) function may know about 'Apple' and handle it properly but library users, even though it is not your intention, may still call eat(Apple) with undefined behaviour.

In summary, the results of calls to eat() and consume() are as follows:

eat( Orange );      // compiles and behaves as expected 
consume( Orange );  // compiles and behaves as expected 
eat( Apple );       // compiles with UNDEFINED BEHAVIOUR
consume( Apple );   // compiles and behaves as expected

The Solution

InheritEnum solves this problem by allowing you to leave the first enum declaration as is and add another enum declaration with new enum types.

Following on from our example, to handle new fruits as well as the first set of fruits, we will then have:

// in -- MyFruit.h --

#include "Fruit.h" 
#include "InheritEnum.h" 

enum NewFruits { Apple, Pear }; 
typedef InheritEnum< NewFruit, Fruit > MyFruit;

Now our consume() declaration becomes:

void consume(MyFruit myfruit); 

Now, our call summary looks as follows:

eat( Orange );       // compiles and behaves as expected
consume( Orange );   // compiles and behaves as expected
eat( Apple );        // does not compile as eat() does not handle NewFruit
consume( Apple );    // compiles and behaves as expected

The Code

// -- InheritEnum.h

template <typename EnumT, typename BaseEnumT>
class InheritEnum
{
public:
  InheritEnum() {}
  InheritEnum(EnumT e)
    : enum_(e)
  {}

  InheritEnum(BaseEnumT e)
    : baseEnum_(e)
  {}

  explicit InheritEnum( int val )
    : enum_(static_cast<EnumT>(val))
  {}

  operator EnumT() const { return enum_; }
private:
  // Note - the value is declared as a union mainly for as a debugging aid. If 
  // the union is undesired and you have other methods of debugging, change it
  // to either of EnumT and do a cast for the constructor that accepts BaseEnumT.
  union
  { 
    EnumT enum_;
    BaseEnumT baseEnum_;
  };
};

Thank you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Lidzhade Fhulu
Web Developer
South Africa South Africa
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalinheriting enums Pin
Atticus-Atropos16-Mar-09 21:34
memberAtticus-Atropos16-Mar-09 21:34 
GeneralRe: inheriting enums Pin
Hugo González Castro2-Apr-09 5:28
memberHugo González Castro2-Apr-09 5:28 
GeneralWorkaround to extend an enum in a derived class Pin
Theo Buys6-Jan-09 0:11
memberTheo Buys6-Jan-09 0:11 
GeneralA different approach Pin
Hugo González Castro23-Dec-08 17:46
memberHugo González Castro23-Dec-08 17:46 
GeneralLicence Pin
warlock6x315-Dec-06 1:43
memberwarlock6x315-Dec-06 1:43 
GeneralRe: Licence Pin
Lidzhade Fhulu17-Dec-06 20:44
memberLidzhade Fhulu17-Dec-06 20:44 
GeneralThere could be simpler way of doing it. [modified] Pin
Mr.Prakash6-Nov-06 20:42
memberMr.Prakash6-Nov-06 20:42 
GeneralRe: There could be simpler way of doing it. Pin
Ivan Kolev6-Nov-06 21:15
memberIvan Kolev6-Nov-06 21:15 
GeneralRe: There could be simpler way of doing it. Pin
Mr.Prakash6-Nov-06 21:23
memberMr.Prakash6-Nov-06 21:23 
GeneralRe: There could be simpler way of doing it. Pin
Lidzhade Fhulu6-Nov-06 23:56
memberLidzhade Fhulu6-Nov-06 23:56 
GeneralRe: There could be simpler way of doing it. Pin
Mr.Prakash7-Nov-06 1:30
memberMr.Prakash7-Nov-06 1:30 
GeneralLooks good at first sight but ... Pin
Roland Pibinger30-Oct-06 23:00
memberRoland Pibinger30-Oct-06 23:00 
... it doesn't work. Try e.g.

void test() {
  MyFruit orange (Orange), apple (Apple);
  if (orange == apple) {
    cout << "oranges are apples" << endl; 
  }
} 
Output:
oranges are apples

Looking at the code operator EnumT() seems to be the problem. Your solution is promising but needs some enhancements.
GeneralRe: Looks good at first sight but ... Pin
Lidzhade Fhulu30-Oct-06 23:21
memberLidzhade Fhulu30-Oct-06 23:21 
GeneralRe: Looks good at first sight but ... Pin
Roland Pibinger30-Oct-06 23:51
memberRoland Pibinger30-Oct-06 23:51 
GeneralRe: Looks good at first sight but ... Pin
Lidzhade Fhulu31-Oct-06 0:30
memberLidzhade Fhulu31-Oct-06 0:30 
GeneralRe: Looks good at first sight but ... Pin
Roland Pibinger31-Oct-06 0:51
memberRoland Pibinger31-Oct-06 0:51 
GeneralRe: Looks good at first sight but ... Pin
Lidzhade Fhulu31-Oct-06 1:01
memberLidzhade Fhulu31-Oct-06 1:01 
GeneralRe: Looks good at first sight but ... Pin
Elv5-Feb-07 10:31
memberElv5-Feb-07 10:31 
GeneralCool Pin
maihem30-Oct-06 13:16
membermaihem30-Oct-06 13:16 
GeneralRe: Cool Pin
Lidzhade Fhulu30-Oct-06 18:14
memberLidzhade Fhulu30-Oct-06 18:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 30 Oct 2006
Article Copyright 2006 by Lidzhade Fhulu
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid