C ++:在类内部使用“enum class”的枚举

6

如何在类中正确地编写枚举?我正在用C++编写康威生命游戏代码。因此,我有一个包含有关不同类型图案信息的模式类:

class Patterns
{
public:
    Patterns();
    ~Patterns(void);

private:
    enum class PatternType
    {
        bloat,
        block,
        blinker,
        toad
    };

    PatternType pattern_;
};

我的目标不是在这里污染全球空间。因此,在考虑面向对象的概念时,在类内部编写枚举的写法是否正确。如果不是,请建议一些更好的替代方案以及它们相对于此方法的优势。欢迎任何关于在类内部编写枚举时需要注意的事项。

编辑:@Jay Miller 根据他的输入,我已经尝试了他的三种方法。

enum class PatternClassOut{ point, circle, triangle };

class Patterns
{
public:
  enum PatternSimple{bloat, block, blinker, toad};
  enum class PatternClassIn{cat, mouse, dog};
  //get set functions for all the enum variables

private:
  PatternClassOut  out_;
  PatternSimple    simple_;
  PatternClassIn   in_;
};

我的发现(尝试代码和谷歌一下后):

  1. PatternSimple是我情况下编写枚举的最简单方法,放在类内部;但它会牺牲类型安全性,即我可以将枚举值与任何其他数据类型进行比较,而不会出现错误。
  2. PatternClassIn提供了类型安全性;但我必须在调用函数中编写更多代码才能访问枚举值。
  3. PatternClassOut提供了两全其美的最佳解决方案。它提供了类型安全性,而且从调用函数访问枚举值的代码与PatternSimple相同。

1
如果枚举是类的公共接口的一部分,那么强制调用者每次在前面加上“Patterns::”前缀可能会变得繁琐。但是,如果像您的示例代码所示,它确实是私有的,那就没问题了。 - dlf
3个回答

3

假设您希望此枚举在类外可用,将其公开化是有意义的。作为一个enum class,您需要使用枚举名称来访问值,除了类名称:

class Patterns {
public:
    enum class PatternType { ... };
...
};
void makePattern(Patterns::PatternType value) { ... };
makePattern(Patterns::PatternType::bloat);

由于这是一个枚举类,将其移出另一个类可能是完全有效的。全局名称空间中唯一新增的内容就是该枚举的名称。

enum class Patterns {
   bloat,
   ...
};
void makePattern(Patterns value) { ... };
makePattern(Patterns::bloat);

如果您希望将其他操作与枚举分组,则像您所做的那样将其嵌套在类中是有意义的。在这种情况下,您可以决定仅使用enum而不是enum class

class Patterns {
public:
    enum PatternType { ... };
    std::string toString() const { ... };
    ...
private:
    PatternType value;
};
...
...
void makePattern(Patterns::PatternType value) { ... };
makePattern(Patterns::bloat);

...::膨胀 ::笑:: - dmckee --- ex-moderator kitten

0

你的方法没问题,唯一的缺点是如果你试图从类外部访问PatternType,它将无法访问,因为它被声明为私有。


2
我不理解你的第二段话。你能详细解释一下吗? - Lightness Races in Orbit
这取决于"污染全局命名空间"是什么意思。如果"污染全局命名空间"指的是在程序启动之前声明全局变量,从而减慢程序初始化速度,并且可以在文件范围内的任何函数中使用它们,则枚举类型不计入其中。但是如果您正在使用c++0x版本,我建议使用枚举类(enum class)来代替。 - Izzy
他正在使用enum class。我还是不太明白你的意思。 - Lightness Races in Orbit
@LightnessRacesinOrbit 我会删除我回答中有疑问的部分。也许我对代码污染的定义有所遗漏。 - Izzy

0

我会把它设为public,但除此之外你已经做得和我一样好了。


有没有办法将enum(或enum class)中的常量批量导入到作用域中,例如类作用域? - Deduplicator
@Deduplicator:enum已经实现了这个功能。enum class的发明部分是为了防止这种情况发生。 - Lightness Races in Orbit
当然,普通的enum会自动使用其直接封闭的作用域。我只是想找到一种方法来使用另一个作用域或者使用enum class和封闭作用域,因为它们之间还有一些其他的区别。 - Deduplicator
@Deduplicator:我不明白。如果你不想利用“enum class”与“enum”的唯一区别,为什么要使用默认基础类型?为什么不使用enum?这毫无意义。 - Lightness Races in Orbit
哪一部分?只有另一个枚举器的一部分枚举器的两个枚举器?根据API,这是相当明智的。隐式/显式部分?我不知道。最后一个想要将所有枚举器作为常量添加到某些/几个类中以方便使用的部分?如果只有一个 - 或者我可以用一个空的基类来解决问题,并且我不关心转换的事情 - 是的,我可以解决它。 - Deduplicator
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接