gpt4 book ai didi

c++ - 使用位运算符理解枚举成员的初始化

转载 作者:太空宇宙 更新时间:2023-11-04 11:31:48 25 4
gpt4 key购买 nike

我目前正在阅读“SFML 游戏开发”一书和第 4 章 - 输入处理子章“接收器类别”中的第 2 段;我们有这个:

“我们定义了一个枚举来引用不同的类别。除了 None 之外的每个类别都用一个整数初始化,其中一位设置为 1,其余设置为 0:”


namespace Category
{
enum Type
{
None = 0,
Scene = 1 << 0,
PlayerAircraft = 1 << 1,
AlliedAircraft = 1 << 2
EnemyAircraft = 1 << 3,
};
}

一般来说,我对按位运算符和二元运算不太满意;所以我不明白那部分“除了 None 之外的每个类别都用一个整数初始化,其中一位设置为 1 ,其余设置为 0 :”。

如果像上面说的那样初始化每个类别(除无),那么“其余”设置为 0 是什么?!

注意:经过仔细阅读,我想我明白枚举的每个成员都是一个字节,因此,那些的第一位设置为 1,同一字节的其他位是设置为 0。所以,Scene = 0b1,PlayerAircraft = 0b10(一个位 = 1,另一个 = 0),等等...所以如果我写:PlayerAircraft = 2 << 1 PlayerAircraft 会等于 0b11 吗?我是对的还是遗漏了什么?

在本章的后面;我们有一个if条件检查请求的类别是否与场景节点一相同;不偏离主题;我不明白那部分。因为它使用 AND (或 & 如果您愿意)按位运算符;它如何检查场景节点类别是否与请求的类别相同?我在维基百科上查过它是如何工作的,但我没有完全理解。

这是代码

void SceneNode::onCommand(const Command& command, sf::Time dt)
{
if(command.category & getCategory()) //The part I don't understand
command.action(*this, dt);
/* ... */
}

我不明白...

Voilà,提前谢谢你,我希望我在这里的第一篇文章不会太乱,并且我已经提供了足够的信息。如果没有,我会编辑! :)

PS:对不起,蹩脚的英语,我今天不够清醒。

最佳答案

什么是operator<<

了解operator<< ,在这种情况下,非常容易。运算符左边是当前值对象;右边是我们应该执行多少次左移。

例如,给定一个对应于 1 的字节:

0 0 0 0 0 0 0 1

向左移动一次会导致:

0 0 0 0 0 0 1 0

现在,如果我们想到 1作为2 ^ 0 ,在每次左移时,我们都会增加指数。因此上面的字节等于2 ^ 1等等:

0 0 0 0 0 0 0 1 // 2 ^ 0 = 1
0 0 0 0 0 0 1 0 // 2 ^ 1 = 2
0 0 0 0 0 1 0 0 // 2 ^ 2 = 4
0 0 0 0 1 0 0 0 // 2 ^ 3 = 8
...

什么是operator&

二进制 operator&是按位与。对于两个位集的每个对应位,结果位为 1如果两个位都是 1 , 0否则。您可以使用它来检查在给定的位集中是否存在特定类别。例如,让我们考虑类别:

0 0 0 0 0 1 0 0

让我们考虑一个表示类别 1 和 2 而不是我们的类别 3 的位集:

0 0 0 0 0 0 1 1

两者之间的按位与将给出 0 (可以隐式转换为 false ):

0 0 0 0 0 1 0 0 &
0 0 0 0 0 0 1 1 =
0 0 0 0 0 0 0 0

另一方面,如果我们的位集(现在代表第一和第三类别)包含我们的类别:

0 0 0 0 0 1 0 0 &
0 0 0 0 0 1 0 1 =
0 0 0 0 0 1 0 0

你会得到一个与 0 略有不同的位集。 (因此可以隐式转换为 true )。

结论

如果您将每个类别表示为位集中的单个位,则可以轻松地在一个位集中表示一组类别。

假设我们要表示四个字母 A , C , G , T .我们可以在长度为四的位集中分配一个位:

0 0 0 1 // A
0 0 1 0 // C
0 1 0 0 // G
1 0 0 0 // T

现在让我们伪造一个代表字母的位集 AG :

0 1 0 1 // A + G

我们可以通过 & 检查给定字母是否在位集中.

有没有A

0 1 0 1 & // A + G
0 0 0 1 = // A
0 0 0 1 // 1 ~ true

是的,有。有没有C

0 1 0 1 & // A + G
0 0 1 0 = // C
0 0 0 0 // 0 ~ false

没有。有没有G

0 1 0 1 & // A + G
0 1 0 0 = // G
0 1 0 0 // 4 ~ true

是的,有。最后,有没有 T

0 1 0 1 & // A + G
1 0 0 0 = // T
0 0 0 0 // 0 ~ false

不,没有。

一般情况

一般来说,给定一个位集a和位集 b对于我们要在 a 中检查是否存在的类别, & 的结果只能是两种:

  1. 0
  2. 分配给类别的值(2 的幂)

在 C++ 中,测试:

if (a & b)

也可以指定为:

if ((a & b) == a)

实例

现在你应该能够理解给定一个 enum喜欢:

enum type
{ none = 0
, scene = 1 << 0
, player_aircraft = 1 << 1
, allied_aircraft = 1 << 2
, enemy_aircraft = 1 << 3 };

和这些变量:

auto a = scene;
auto b = enemy_aircraft;
auto c = player_aircraft;

以下内容:

    std::cout << "a is of type: " << ((a & scene) ? "scene" : "not scene") << '\n';    
std::cout << "b is of type: " << ((b & enemy_aircraft) ? "enemy_aircraft" : "not enemy_aircraft") << '\n';
std::cout << "c is of type: " << ((c & player_aircraft) ? "player_aircraft" : "not player_aircraft") << '\n';

将打印:

a is of type: scene

b is of type: enemy_aircraft

c is of type: player_aircraft

Live demo

关于c++ - 使用位运算符理解枚举成员的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24440952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com