8 に答える
C++11 の新機能である厳密に型指定された列挙を使用してみてください。そのおかげで、名前の競合がなくなり、非常に強力な型システムになります。
これにはenumクラスを使用できます
enum class State
{
Accelerating,
Breaking,
Stopped
};
次に、必要に応じて State::Breaking として参照します。これにはもちろん c++11 が必要です。http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerationsを参照してください。
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)
class GameCharacter {
public:
class MovingState {
MovingState();
/* or, in C++11:
* MovingState() = delete;
*/
public:
enum State {
Running,
Walking,
Stopped // Referred as GameCharacter::MovingState::Stopped.
};
};
class DrivingState {
DrivingState();
/* or, in C++11:
* DrivingState() = delete;
*/
public:
enum State {
Accelerating,
Breaking,
Stopped // Referred as GameCharacter::DrivingState::Stopped.
};
};
...
};
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?
C++1x (昨年標準化された C++ の新しいバージョン) では、厳密に型指定された列挙型を使用できます。これにより、列挙型クラス自体のスコープに識別子が配置されます (その他の改善点の中でも特に)。これらは次のように宣言されenum class
ます。
class GameCharacter {
public:
enum class State {
Running,
Walking,
Stopped // Referred to as GameCharacter::MovingState::Stopped.
};
...
};
それまでの間、C++03 コンパイラに行き詰まっている場合、または互換性を維持したい場合は、class
代わりに使用namespace
して、独自の回答で提案したようにコンストラクターをプライベートに宣言してください。class
外の世界が見る必要がない場合は、全体を非公開にすることができます。
C ++ 11の強く型付けされた列挙型を使用できない場合は、名前空間の代わりに構造体を使用できます。
class GameCharacter {
public:
struct MovingState {
enum Enum {
Running,
Walking,
Stopped
};
}
...
};
これは、名前空間のトリックとは異なり、どこでも使用できるため、しばらくの間(C ++ 11がサポートされるまで)採用したものでした。
これは、C++11 のStrongly Typed Enumerationsの仕事のように思えます。
class GameCharacter {
public:
enum class MovingState {
Running,
Walking,
Stopped
};
...
void f(Movingstate m) { if (m == MovingState;:Running) ... }
};
void f() { if (mm == GameCharacter::MovingState::Running) ... }
C++11 を使用している場合は、
class GameCharacter {
public:
enum class DrivingState { Accelerating, Breaking, Stopped };
enum class WalkingState { Stopped, Running, Walking };
DrivingState driving_state() { return ds_; }
void set_driving_state(DrivingState ds) { ds_ = ds; }
WalkingState walking_state() { return ws_; }
void set_walking_state(WalkingState ws) { ws_ = ws; }
DrivingState ds_;
WalkingState ws_;
};
int main() {
GameCharacter g;
g.set_walking_state(GameCharacter::WalkingState::Stopped);
g.set_driving_state(GameCharacter::DrivingState::Stopped);
return 0;
}
名前空間にサブカテゴリ化する必要があると感じるクラスが多すぎる場合は、クラスに含まれるものが多すぎます。
そこから物を移動する必要があります。特に、これらすべての列挙型はクラスのメンバーである必要はありません。クラスと同じ名前空間にそれらを保持しないのはなぜですか?