C++ 枚举标志用法

标签 c++ enums

我用谷歌搜索了一下,但似乎没有立即可用的明确答案。我试图弄清楚枚举标志在 C++ 中的正确用法。我正在开发一个基于 2D tile 的平台游戏引擎,我想给每个 tile 标志来确定哪些边缘可以与之发生碰撞。

在一个文件中我有:

enum CollidableEdges
{
    TopEdge = 1,
    RightEdge = 2,
    BottomEdge = 4,
    LeftEdge = 8
};

我如何在对象中实际调用这些标志并稍后在逻辑中使用它们?在我在网上看过的例子中,它似乎没有在操作标志时在初始列表之外的任何地方声明枚举。有人可以澄清到底发生了什么以及如何使用它吗?例如,当创建一个具有如下定义的新 Tile 对象时:

class Tile: public Entity
{
    public:
        Tile(std::string obstacleTexture, int, int);
}

我是一个相当新的程序员,所以我确信我使用了错误的做法或者遗漏了一些明显的东西。不要害羞告诉我。

最佳答案

Can someone clarify what exactly is happening and how to use it?

初始化特定位

uint8_t flags = uint8_t(TopEdge) | uint8_t(LeftEdge);

设置特定位

flags |= uint8_t(BottomEdge);

清除特定位

flags &= ~(uint8_t(TopEdge) | uint8_t(LeftEdge));

测试特定位

if(flags & uint8_t(BottomEdge) > 0) { // Flag is set (BottomEdge)
}

你需要转换它的原因是因为如果你有一个像 TopEdge | 这样的表达式LeftEdge 编译器不会接受原始 enum 类型作为结果。

要摆脱强制转换,您还可以定义重载的operator|()operator&() 等:

CollidableEdges operator|(CollidableEdges  left, CollidableEdges right) {
    return static_cast<CollidableEdges>(static_cast<unsigned>(left) | 
                                        static_cast<unsigned>(right));
}
// etc.

允许简单地编写

CollidableEdges edges = TopEdge | LeftEdge;

注意:
尽管上述语句可以正常工作,但恕我直言,它们对预期语义的可读性很差。我个人更喜欢以下解决方案:

 enum class CollidableEdgeBitPos : size_t {
    TopEdge ,
    RightEdge ,
    BottomEdge ,
    LeftEdge 
 };

 typedef std::bitset<4> CollidableEdges;

 CollidableEdges edges;

 edges[CollidableEdgeBitPos::RightEdge] = true;
 edges[CollidableEdgeBitPos::BottomEdge] = false;

关于C++ 枚举标志用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22917937/

相关文章:

c++ - 返回特定于类的枚举

c++ - 遵循代码流程

java - 从子类中定义的枚举调用方法 - Java

java - 如何使用 Hibernate/JPA 将 JAVA 枚举映射到 Postgresql 枚举?

python - 如何优雅地找到 Python 枚举中的下一个和上一个值?

c++ - 找到除数的数量不知道出了什么问题

c++ - 如何将字符数组中的前 i 个字符复制到 C++ 中的另一个字符数组中?

c++ - C++ 中空枚举的大小如何为 4?

c - 在 GCC 中分配或执行具有不同枚举类型的算术时如何发出警告?

c++ - 我怎样才能让两个类通过 C++ 中的 vector (映射、多映射..)相互链接?