Enum type as a member variable.

Hi.

When you use enum type as a member variable, what do you use for the member variable's real type?

I mean, If you want a variable for a color, you will declare a enum data.

1
2
3
4
5
6
enum eColor
{
RED  = 0,
GREEN,
BLUE
};


and you will implement a class.

1
2
3
4
5
6
7
class MyClass
{
...
// you have two choice.
   eColor m_eColor;  // (1)
   int    m_iColor;  // (2)
}


If you want to use the case(1) you can use like this for a initialization.

 
MyClass* pObj = new MyClass(eColor::RED);


but if you use the case(2) you should use casting.
 
MyClass* pObj = new MyClass(static_cast<int>(eColor::RED));


Which is the more good way? It will be nice if you consider use of setter/getter.
If you make the effort to define an enum, why on earth would you go to the trouble of casting it to and from an int in the interface? If there's value in using an enum, then use the enum wherever appropriate to get the most value from it.
Last edited on
When you have a basic enum (without class) you don't need a cast to use it as int.
Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

class Myclass {
public:
	static enum eColor { RED = 0, GREEN, BLUE };

	eColor getColor() const { return m_eColor; }
	void setColor(eColor color) { m_eColor = color; }

private:
	eColor m_eColor;
};

int main()
{
	Myclass mc;

	mc.setColor(Myclass::BLUE);

	std::cout << "Colour is " << mc.getColor() << '\n';
}

Last edited on
coder777 // Sorry for my mistake. I meant a enum class.
MikeyBoy // because I needed a integer value in other part. somewhere needs value as a int.. somewhere needs value as a enum.. But I agree with you. maybe my design pattern was wrong..
seeplus // Thank you. I will consider it.
MikeyBoy // because I needed a integer value in other part. somewhere needs value as a int.. somewhere needs value as a enum.. But I agree with you. maybe my design pattern was wrong..


In which case, I would keep the quantity as an enum as much as possible, and only convert to an int at the point you really need to. (And also, re-examine whether you need to use it as an int at all.)
MikeyBoy // Thank you :)

And how about this case? there is a enum data for a speed. and you need a speed for calculating distance.

 
int distance = sec * static_cast<int>(pObj->GetSpeed());


Even if the code will be used in many times, it is not a big deal?
I can hardly make any judgement of your design when you present me with a single line of code, can I?

Given such little material to work with, my question would be - why is a quantity called "speed" expressed as an enum? Speed is a numerical quantity, and, usually, a continuous one.
Given a scoped enumeration like
enum class speed: int {};
It is possible to (direct-list-)initialize 'speed' with an int, for example
speed s{42}; // ok
If it makes sense to add speeds, OP can overload operator+ for them, and leave nonsense like bit-manipulations undefined. std::byte is specified this way.

If you're in the habit of accidentally typing bit_or where you meant or, this definition may save you a logic error.

In my opinion this feature misses that writing scoped enumerations, especially ones such as speed, is rarely worth the effort.
Last edited on
I'm implementing simple game like the Galaga. and there are some value for speed like player's speed, ammo's speed..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum class eSpeed
{
   SPEED_PLAYER = 8,
   SPEED_AMMO = 16,
   SPEED_ENEMY = 16,
...
};

...
ObjectManager<Ammo>* pAmmoMng = new ...(eSpeed::SPEED_AMMO);
...

...
// Calculate a next position.
curAmmoPos.x += pAmmoPos->GetSpeed();
...


I think operator overloading is great idea, but still doesn't use casting internally?
I believe there is a time and a place for both types of enum.
if you need a group of integer constants, the old C enum is useful: you don't have to cast it or do anything, just use it.
if you need type safety, so you cant say idiotic things like myspeed= lemons or myfruit = speed_ammo, then the class prevents you from doing that by forcing you to use the enum's type or to explicitly cast it away. It is understood that if you are casting it, you have considered what you are doing to make sense: no accidental type mismatching but deliberate decision. If your enums and the constants in them had good names, it should be obvious that you messed up even the C style enum.
there is also a middle path: you can put a C style enum into a namespace (or a struct, you can hand-roll your own thing too with built in sanity checks or other functionality), allowing use of the values without casting while protecting you from name collisions and forcing a scope resolution on them to clarify which constant group you are working with:
playerspeed = speedstuff::speed_player;
playerspeed = fruitstuff::lemons; //what? if this didn't tell you something was wrong, there is no hope.

once you make the decision which enum type to use, then you cast or not:
if you used the C enum, you do not need to cast anything; they behave exactly like int constants.
if you used the enum class, you will have to cast it, frequently if you need the numeric value. It cannot be avoided; that is what the class DOES.
you can screw either one of them up: you can cast the enum class and use that incorrectly, and you can use an enum in various unsafe ways.
Last edited on
jonnin // Thank you for your advice! I understood that I have to choose from two options.
Topic archived. No new replies allowed.