Search code examples
c++c++11enumsmultiple-inheritance

inheritance just to share enum - dangerous?


Whenever I want to share an enum among many files I will :-

  • create a class e.g. B dedicated to the enum
  • a class, which want to access to the enum easily, will derived from B

Mostly, there will be one class for one enum. (1:1)

class B{
    public: enum EnumB{ E1,E2 };  
};
class C : public B{ /* .... access EnumB */}; //a kind of struct
class D : public B{ /* .... access EnumB */}; //a kind of widget/manager

This approach enables C and D to access EnumB without any prefix B.

I think it is OK, because I use those enum in a very-narrow scope. (2-4 classes)
A SO post also states it is OK to use inheritance for utility.

However, I don't find that it is a popular approach :-

Question

  • How my approach is dangerous? What is its disadvantages?

    In real case, I tend to multi-inherit many classes just for that.

    class ShadowEnum{ public: enum ShadowE{ SHADOW,NO_SHADOW};   };
    class ColorEnum{  public: enum ColorE{ RED,BLUE,GREEN,PURPLE } };  
    class LightType{  public: enum LightE{ L_SPHERE, L_CONE, L_SPOT};   };   
    class LightManager : public ShadowEnum, public ColorEnum,public LightType{
         /* some code */
    };
    
  • Can it be a cause of a dread-diamond issue in future?

By the way, I think enum-class is not in the scope of this question.


Solution

  • It's not "dangerous" per-se. It's just bad design.
    Class inheritance is supposed to define an IS-A relationship.

    When inheriting from something that isn't "natural", you tend to get problems later along the development road.

    Some of this design implications that could affect you are:
    1. Multiple inheritance of the same class in a deeper inheritance graph.
    2. Pointer casts may be affected if you change the inheritance structure in the future (Which is something you don't want to happen just for a convenience inheritance)

    A couple of better solutions:
    1. Contain the enums in a namespace - use #using namespace. Adding that in the header will propagate to any compilation unit that includes that header.
    2. In C++11 you can just use enum classes - Not in inheritance, but it gives you stronger type safety.