The problem is C++ does not allow namespace declarations within classes.(I searched on internet and found this; if it's not true, please say it) So, what's the best way to cheat this problem?
Context: My class have an enumeration within it.
class GameCharacter {
public:
enum MovingState {
Running,
Walking,
Stopped
};
...
};
OBS: This example is not real, it's totally hypothetical.
C++ defines that the enumeration names are inside the class scope, then to use these states I have to use the scope operator directly from the class name(GameCharacter::Running
, for instance; or using GameCharacter::Running
).
I think this is bad, because the name which belongs to the enumeration is inside the class scope; I wanted to have a scope for the RunningState enumeration. (accessing it this way: GameCharacter::MovingState::Running
)
My first thought, then, was to create a namespace which would define a scope for the enumeration.
class GameCharacter {
public:
// does not compile
namespace MovingState {
enum State {
Running,
Walking,
Stopped
};
};
...
};
But C++ forbids it. This code does not compile. (main.cpp:3:5: error: expected unqualified-id before ‘namespace’
)
The reason why I'm trying to do things this way is because there is a possibility to create an second enumeration with names in same scope. Which could cause conflicting names.
class GameCharacter {
public:
enum MovingState {
Running,
Walking,
Stopped
};
enum DrivingState {
Accelerating,
Breaking,
Stopped // Compilation error: conflicts with previous declaration ‘GameCharacter::MovingState GameCharacter::Stopped’
};
...
};
(my idea was that, in this case, the states should be referred as GameCharacter::MovingState::Stopped
and GameCharacter::DrivingState::Stopped
)
Then, what should I do?
An alternative I found was to, instead of namespace, use classes, but the problem is this way the project is not clear enough and classes can be instantiated. (Although I can cheat this problem with private constructors)
this works, but I'm not very clear if this is the best solution. I think there should be another way. I want opinions. What do you think?
In C++1x (the new version of C++ that was standardised last year), you can use strongly typed enumerations, which put the identifiers in the scope of the enum class itself (among other improvements). These are declared with
enum class
:In the meantime, if you're stuck with a C++03 compiler or want to retain compatibility, just use
class
instead ofnamespace
and declare the constructor private as you suggested in your own answer. You can make the entireclass
private if the outside world doesn't need to see it.If you use C++11, you can use
You can use enum class for this
Then you'd refer to it as State::Breaking as you wanted. This of course requires c++11, see http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations
You can use a struct instead of a namespace if you are unable to use C++11 strongly typed enums:
This was something that we adopted for a while (until C++11 support) as it can be used everywhere unlike the namespace trick.
Try using new C++11 feature - strongly typed enumerations. Thanks to it you will not have name collisions and you will end up with really strong type system.