6

What would be the right way to write an enum inside a class? I am writing conway's game of life code in c++. So i have a patterns class which contains the info about different kind of patterns:

class Patterns
{
public:
    Patterns();
    ~Patterns(void);

private:
    enum class PatternType
    {
        bloat,
        block,
        blinker,
        toad
    };

    PatternType pattern_;
};

My goal is not to pollute the global space here. So is it the write way of writing the enum inside of a class keeping oops concepts in mind. If not, please suggest some better alternatives and what are their benefits over this method. Any inputs on keeping things in mind while writing enums inside of a class are welcome.

Edit: @Jay Miller Based on his inputs i have tried all of his three methods

enum class PatternClassOut{ point, circle, triangle };

class Patterns
{
public:
  enum PatternSimple{bloat, block, blinker, toad};
  enum class PatternClassIn{cat, mouse, dog};
  //get set functions for all the enum variables

private:
  PatternClassOut  out_;
  PatternSimple    simple_;
  PatternClassIn   in_;
};

My findings (After trying out the code & googling a bit):

  1. PatternSimple is the simplest way to write the enum in my case, inside of the class; but it compromises on type safety i.e i can compare the enum values with any other data type and it wont give any error.
  2. PatternClassIn provides type safety; but i have to write more code in the calling funcion, to access the enum values.
  3. PatternClassOut provides the best of both worlds. It provides type safety, moreover, the code from the calling function to access enum values is same as that of PatternSimple.
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
divine-code
  • 107
  • 2
  • 6
  • 1
    If the enum were part of the class's public interface, it might become cumbersome forcing callers to stick the `Patterns::` prefix in front of it every time. But if it really is private as your example code shows, that's fine. – dlf Nov 20 '14 at 16:07

3 Answers3

3

Assuming you want this to be available outside your class, making the enum public makes sense. As an enum class, you will need the enum name to access the values in addition to the class name:

class Patterns {
public:
    enum class PatternType { ... };
...
};
void makePattern(Patterns::PatternType value) { ... };
makePattern(Patterns::PatternType::bloat);

Because it is an enum class, it may be perfectly valid to move it outside of another class. The only addition to the global namespace will be the name of the enum.

enum class Patterns {
   bloat,
   ...
};
void makePattern(Patterns value) { ... };
makePattern(Patterns::bloat);

If you have other operations you want to group with the enum then nesting it in a class as you have makes sense. You may decide, in that case, to just use enum rather than enum class:

class Patterns {
public:
    enum PatternType { ... };
    std::string toString() const { ... };
    ...
private:
    PatternType value;
};
...
...
void makePattern(Patterns::PatternType value) { ... };
makePattern(Patterns::bloat);
Jay Miller
  • 2,184
  • 12
  • 11
0

Your approach is ok, only drawback would be if you are trying to access PatternType from outside the class it would be unreachable since it is declared private.

Izzy
  • 402
  • 6
  • 16
  • 2
    I don't follow your second paragraph. Can you expand on it? – Lightness Races in Orbit Nov 20 '14 at 16:10
  • It depends what polluting global namespace means. If polluting global namespace means declaring global variables that are to be initialized before program start, slowing the program initialization and to be available from any single function within the scope of the file, enum doesn't count toward it. On a second notice if you are using c++0x I would use enum class instead. – Izzy Nov 20 '14 at 16:22
  • He _is_ using `enum class`. I'm still not really following you. – Lightness Races in Orbit Nov 20 '14 at 16:37
  • @LightnessRacesinOrbit I will remove questioned part of my answer. Maybe I am missing meaning of code pollution definition. – Izzy Nov 20 '14 at 16:43
0

I'd make it public, but otherwise you've done it just as I would.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Is there any way to import the constants from an `enum` (or `enum class`) wholesale into a scope, like class-scope? – Deduplicator Nov 20 '14 at 16:17
  • @Deduplicator: `enum`s already do that. `enum class` was invented in part to _stop_ that from happening. – Lightness Races in Orbit Nov 20 '14 at 16:36
  • Sure plain `enum`s do that automatically with the immediately enclosing scope. I just want a way to do it with another scope, or with `enum class` and the enclosing scope because there are a few other differences. – Deduplicator Nov 20 '14 at 19:56
  • @Deduplicator: IDGI. Why do you use `enum class` with a default underlying type if you don't want to take advantage of the _sole_ remaining difference to `enum`? Why not use `enum`? This makes no sense. – Lightness Races in Orbit Nov 20 '14 at 20:34
  • conversion to underlying integral type is implicit for unscoped and explicit for scoped enumerations. Also, I might for some reason want to add all enumerators of one enum in the declaration of another, or for some reason only known to me add add them to some class(es), though I did not define the enum in it. – Deduplicator Nov 20 '14 at 20:46
  • @Deduplicator: That's weird. – Lightness Races in Orbit Nov 20 '14 at 20:54
  • Which part? Having two enums with only part of the enumerators of another enum? Quite sensible, depending on the API. The implicit/explicit part? I don't know. The last one with wnating to add all the enumerators as constants to some/a few classes as a convenience? Well, if there is only one - or I can get away with an empty base-class and I don't care about the conversion thing - yes, I can work around it. – Deduplicator Nov 20 '14 at 21:01