什么是类中名称空间的好替代方法
What is a good alternative to namespaces within classes?
问题是C 不允许在类中命名空间声明(我在Internet上搜索并找到了;如果不是真的,请说出来)问题?
上下文:我的班级内有一个枚举。
class GameCharacter {
public:
enum MovingState {
Running,
Walking,
Stopped
};
...
};
obs:这个示例不是真实的,它是完全假设的。
c 定义了枚举名称在类范围内,然后要使用这些状态,我必须直接从类名称使用范围操作员(例如 GameCharacter::Running
;或 using GameCharacter::Running
)。
我认为这很糟糕,因为属于枚举的名称在班级范围内;我想拥有RunningState枚举的范围。(以这种方式访问:GameCharacter::MovingState::Running
)因此,我的第一个想法是创建一个名称空间,该命名空间可以定义枚举范围。
class GameCharacter {
public:
// does not compile
namespace MovingState {
enum State {
Running,
Walking,
Stopped
};
};
...
};
但是C 禁止它。此代码不编译。(main.cpp:3:5: error: expected unqualified-id before ‘namespace’
)
我试图以这种方式做事的原因是因为有可能在同一范围中创建第二个枚举。这可能会导致矛盾的名字。
class GameCharacter {
public:
enum MovingState {
Running,
Walking,
Stopped
};
enum DrivingState {
Accelerating,
Breaking,
Stopped // Compilation error: conflicts with previous declaration ‘GameCharacter::MovingState GameCharacter::Stopped’
};
...
};
(我的想法是,在这种情况下,应将国家称为GameCharacter::MovingState::Stopped
和GameCharacter::DrivingState::Stopped
)那我该怎么办?
尝试使用新的C 11功能 - 强烈键入枚举。多亏了它,您将没有名字碰撞,最终将获得真正强大的类型系统。
您可以将枚举类用于此
enum class State
{
Accelerating,
Breaking,
Stopped
};
然后,您将其称为状态::打破。当然,这需要C 11,请参见http://en.wikipedia.org/wiki/c+++11#stronglonglonglong_typed_enumerations
在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
我发现的另一种替代方案是使用类,而是使用类,但是问题是该项目不够清晰,可以实例化类。(尽管我可以用私人构造函数欺骗这个问题)
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.
};
};
...
};
这有效,但是我不清楚这是最好的解决方案。我认为应该有另一种方式。我想要意见。你怎么看?
这听起来像是C 11的强烈打字的工作。
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;
}
如果您无法使用C 11强键入枚举,则可以使用struct而不是名称空间:
class GameCharacter {
public:
struct MovingState {
enum Enum {
Running,
Walking,
Stopped
};
}
...
};
这是我们一段时间采用的东西(直到C 11支持),因为它可以与名称空间技巧不同。
如果您的班级有很多东西,以至于您需要将其子类别化为名称空间,则您的类有太多东西。
您应该将东西从中移出。特别是所有这些枚举都不需要成为班级的成员。为什么不将它们保留在同一级别的命名空间中?
- 如何通过命名空间调用非静态方法
- 转发声明在命名空间中不起作用的替代方法
- 使用 GMock 的具有命名空间的模拟方法
- 在方法定义中显式指定命名空间
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- C++详细介绍命名空间 vs 匿名 vs 私有方法到类 vs. pimpl vs. 朋友类
- 有什么方法可以"factor out"公共字段以节省空间?
- 请告诉我在巴泽尔拥有多平台工作空间的更好方法
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 是否有一种方法可以避免标头文件中使用的constexpr函数输入全局范围,而无需额外的名称空间
- 声明方法时没有名称空间,也没有对C 作用的方法的对象
- 从类方法调用命名空间中名为 Same 的函数时,重载解析失败
- 在嵌套名称空间范围中使用名称空间的正确方法
- 此插入方法的时间和空间复杂性
- 为在与类方法中的类相同的命名空间中定义的结构调用重载运算符
- 有没有一种方法可以创建具有广义属性的命名空间
- 有什么方法可以将此功能分开并插入空间
- 在某些名称空间中定义方法时,在全局名称空间中声明
- Singleton实现:与Singleton类相比,名称空间方法通常更可取吗
- 当类方法不进行时,为什么从标头文件中的独立方法需要为命名空间资格