C ++设置“标志”

时间:2010-04-04 13:43:30

标签: c++ design-patterns

示例:

enum Flags
{
    A,
    B,
    C,
    D
};

class MyClass
{
   std::string data;
   int foo;

   // Flags theFlags; (???)
}
  • 如何实现可以在MyClass实例中在枚举中设置任意数量的“标志”A,B,C和D?

我的目标是这样的:

if ( MyClassInst.IsFlagSet( A ) ) // ...
MyClassInst.SetFlag( A ); //...
  • 我是否必须使用某些数组或向量?如果是,怎么样?
  • 在这种情况下,枚举是个好主意吗?

4 个答案:

答案 0 :(得分:3)

// Warning, brain-compiled code ahead!

const int A = 1;
const int B = A << 1;
const int C = B << 1;
const int D = C << 1;

class MyClass {
public:
  bool IsFlagSet(Flags flag) const {return 0 != (theFlags & flag);}
  void SetFlag(Flags flag)         {theFlags |= flag;}
  void UnsetFlag(Flags flag)       {theFlags &= ~flag;}

private:
   int theFlags;
}

答案 1 :(得分:2)

在C中,您可以手动设置特殊(非连续)枚举值:

enum Flags
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
};

最好使用类型安全:

const int A = 1;
const int B = 2; /* ... */

因为(A | B)不是您的枚举值之一。

答案 2 :(得分:0)

不,您不必使用数组或向量,但您需要的是按位比较。

第一步是将每个标志的数值设置为指数值2(ex-1,2,4,8,16,32,64等等),所以二进制看起来像0001,0010,0100,1000等。

现在,要设置或删除标志,您需要将其添加到Flag变量,或将其删除。检查标志的示例如下:

if(MyClass.Flags & FLAG_A)
{
    // Flag is set
}

if(!(MyClass.Flags & FLAG_B))
{
    // Flag is not set
}

答案 3 :(得分:0)

如果foo是你的位标志,你可以通过以下方式设置A on foo:

foo |= A

通过执行以下操作在foo上取消设置:

foo &= (~A)

通过检查此表达式是否为真来检查是否在foo上设置了

(foo & A) == A

但你必须确保A,B,C,D的值设置正确(0x01,0x02,...)