【发布时间】:2011-02-07 11:32:12
【问题描述】:
我知道可以在枚举值中使用位掩码,但我不知道如何创建它。
我有一个简单的枚举:
enum State
{
minimizing = 0,
maximizing,
minimized,
maximized
};
状态始终为State.minimized 或State.maximized,并且可以在调整大小时具有其他状态。所以有些东西可以最大化和最小化
【问题讨论】:
我知道可以在枚举值中使用位掩码,但我不知道如何创建它。
我有一个简单的枚举:
enum State
{
minimizing = 0,
maximizing,
minimized,
maximized
};
状态始终为State.minimized 或State.maximized,并且可以在调整大小时具有其他状态。所以有些东西可以最大化和最小化
【问题讨论】:
我将假设myState 具有您的enum State 的类型。
enum 的传统用法是创建这种类型的变量可以采用的常量值。您希望将变量myState 设置为enum 中定义的值的组合。
enum 将 1、2、4 和 8 定义为有效值,但您希望能够将变量设置为 4 | 2 = 6。虽然 C 对所有 enum 使用实现定义的 int 类型,但在 C++ 中并非如此。 myState = 6 在 C++ 中无效。实际上,myState = 4 在 C++ 中无效,您需要显式转换或使用 enum 的常量名称之一。
尽管在 C 语言中可行,但将 myState 设置为未由其类型定义的值(例如设置为 6)并不是一个好习惯。
在您的情况下,似乎随之而来的解决方案是:
typedef enum {
OTHER,
MINIMIZED,
MAXIMIZED
} win_size_t;
typedef struct {
win_size_t current;
win_size_t next;
} state_t;
state_t myState;
这样,您可以独立地写入字段current 和next。
如果您仍然想要位字段,您可以设置结构元素的大小(以位为单位)。这有点危险,位域的实现取决于你的编译器。我什至不确定编译器是否会接受在位字段中使用枚举类型(在 C 中应该可以,因为 enums 是 int)。
typedef struct {
win_size_t current : 2; // not tested
win_size_t next : 2;
} state_t;
前面给出的解决方案当然是有效的。我的观点是,如果你的变量 myState 有你的 enum State 作为类型,它应该只使用 enum 的成员作为其值,而不是组合。
可能myState有其他类型,我知道什么。
如果myState 不属于enum State 类型,则可以组合使用enum 中定义的常量。
enum State {
MINIMIZING = (1u << 0),
MAXIMIZING = (1u << 1),
MINIMIZED = (1u << 2),
MAXIMIZED = (1u << 3),
};
unsigned int myState = 0;
myState |= MAXIMIZED; // sets that bit
myState &= ~MAXIMIZED; // resets that bit
这使您可以在一项作业中做两件事:
myState = MAXIMIZED | MINIMIZING;
还有你可能不想要的东西:
myState = MAXIMIZED | MINIMIZED; // does that make sense?
【讨论】:
MAXIMIZED | MINIMIZED 是可能的,这毫无意义,因为有两个枚举更好的可读性。
对枚举中的每个值使用不同的位,例如:
enum State
{
minimizing = 0x01, // 00000001
maximizing = 0x02, // 00000010
minimized = 0x04, // 00000100
maximized = 0x08 // 00001000
}:
然后,您可以使用按位或 (minimizing | maximized) 组合多个值,并使用按位和 (bool is_minimized = (flags & minimized);) 测试值。
【讨论】:
(1u << 0)、(1u << 1)、(1u << 2)、(1u << 3)。你的意思更清楚了。
minimizing = 1 也有效
我刚刚在 VS2012 中尝试过,如果您使用的是位域,优化器似乎可以正确组合位而无需任何帮助。
struct BITS { int x: 1; int y:1; };
然后
BITS b;
b.x = b.y = 1;
用一条指令设置两个位。
【讨论】:
您可以通过指定枚举中的所有字段并增加 2 的幂来获得此效果,以获得位掩码效果。例如,在您的情况下:
enum State
{
minimizing = 1,
maximizing = 2,
minimized = 4,
maximized = 8
};
这样您就可以拥有(State.maximized | State.minimizing) 的组合。但是,这不会应用仅限于 State.maximized 或 State.minimized 的限制。如果你想这样做,你可以将它们转换为单个位,但我想在这个例子中你希望能够有一个既不最大化也不最小化的情况。
【讨论】:
myState = minimized; if (isMaximizing) { myState = maximizing } 我想设置最大化状态,而不会丢失最小化状态
myState |= maximizing;。这会设置您感兴趣的位,而不会触及其他位。对于归零,使用myState &= ~maximizing;。比较时要小心,myState == minimized 不起作用,你需要(myState & minimized) == minimized(或!= 0)。如果我是你,我会考虑一个结构体,其中一个字段为“当前状态”,另一个字段为“下一个状态”。
enum State 定义了一些常量,但它没有定义它们的组合。如果myState被最小化和最大化,则结果值为0x02 | 0x04,即0x06。不是您的枚举定义的值。