[solved] enum -- OOP hostile?

Enumerations seem to break the rules of OOP. My understanding is that changes to the implementation should be invisible to the interface, but that's not really the case with enum types, afaics.

1
2
3
4
5
6
7
8
class this_class{
public:
enum evil {not, somewhat, mostly, very};
...
private:
evil m_evil;
...
};

In a program that uses this class:

this_class evilness = this_class(this_class::very)
Not transparent, implementation can't be changed without changing the interface

How to make this transparent to the interface? The only way I see is jockeying around const, either in the header, implementation, or program.

1
2
3
const this_class::evil very = very; // really?! This seems absurd to me.

this_class evilness = this_class(very) // yeah it works, but... seriously?! 


Can someone please explain this better to me? I can't help but think this is a broken idea. Thanks.
Last edited on
enums are not part of the implementation, they are types just like classes. Their only purpose is to remove the need of meaningless literal constants (would you prefer to see 8845935 or this_class::evil?). They are an improvement (sort of) over #defined constants in that they allow the compiler to do type checking.
I'm not sure what you're expecting of them.
I wanted to use the enum to make sure that anyone using the class could not assign an integer value to m_evil (in this example) and exceed the limits of the enumeration. If the constructor accepts formal parameter of type evil, then the user must specify something in the enumeration -- not just an integer -- so in this case it isn't really acting as a symbolic constant.

1
2
3
4
5
this_class evilness = this_class(2) // compiler error
this_class evilness = this_class(this_class::mostly) // same value, but needs scope resolution
const this_class::evil mostly = mostly;
this_class evilness = this_class(mostly) /* now works, is OOP, doesn't require scope resolution
but does require a const for each enum value to be declared in addition to defining the enumeration*/

The problem is, it breaks OOP because OOP says if I change the implementation (by changing enum evil to an integer on a whim) that I will have broken the interface because this_class::very no longer exists. In fact, when anyone using the class types in this_class::very as a formal parameter, they automatically KNOW it's an enumeration (if they know C++) because any other basic type would not require scope resolution.

That is my beef with type enum: each value requires scope resolution in the program in order to use it. The only way I found around that is what I originally posted -- using a symbolic constant that stands in for an enumeration value of the same name. That just doesn't seem right to me.

Please accept that I am very new at C++, I'm only on chapter 10 of Prata, but I found this dilemma by accident and it puzzled me. I guess I don't really have a specific question about enumerations -- more specifically, I was hoping someone would look at how I was using it, and say, "Ah... there is a better way to do what you intend, and here it is:" followed by their wisdom.
changing enum evil to an integer
You're still confused. That's like saying "if I change this_class to an int".
What you need to understand is that enums are types, just like classes. evil is not some thing of type enum. evil is a type in itself, just like this_class is a type, and not some thing of type class. What you could so is change each of its... enumerated elements to a different type. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class this_class{
public:
static const int not;
static const int somewhat;
static const int mostly;
static const int very;
enum evil {not, somewhat, mostly, very};
...
private:
evil m_evil;
...
};

this_class::not=0;
this_class::somewhat=1;
this_class::mostly=2;
this_class::very=3;

That didn't really change much, since you still have to refer to them by this_class::.


If what's bothering you is the scope, why don't you just move the enum out of the class?
Last edited on
1
2
changing enum evil to an integer
You're still confused. That's like saying "if I change this_class to an int".

Sort of. What I meant by that was this -- not altering the type itself, but replacing it with another type:

1
2
3
4
5
6
7
8
9
class this_class{
public:
// get rid of enum evil {not, somewhat, mostly, very};
int evil; // change to type int instead - this breaks the interface
...
private:
evil m_evil;
...
};


If what's bothering you is the scope, why don't you just move the enum out of the class?
And there is the pearl of wisdom I was looking for! I thought if I moved the enum out of the class, then private: evil m_evil would not understand what type evil was when I tried to compile. I thought anything used by the class had to be defined in the class.
Thanks!
Topic archived. No new replies allowed.