我用谷歌搜索了一下,但似乎没有立即可用的明确答案。我试图弄清楚枚举标志在 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/