简体   繁体   English

C ++设置“标志”

[英]C++ setting up “flags”

Example: 例:

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

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

   // Flags theFlags; (???)
}
  • How can I achieve that it is possible to set any number of the "flags" A,B,C and D in the enum above in an instance of MyClass? 如何实现可以在MyClass实例中的上面的枚举中设置任意数量的“标志” A,B,C和D?

My goal would be something like this: 我的目标将是这样的:

if ( MyClassInst.IsFlagSet( A ) ) // ...
MyClassInst.SetFlag( A ); //...
  • Do I have to use some array or vector? 我必须使用一些数组或向量吗? If yes, how? 如果是,怎么办?
  • Are enums a good idea in this case? 在这种情况下,枚举是个好主意吗?
// 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;
}

In C, you set special (non-sequential) enum values manually: 在C中,您可以手动设置特殊(非顺序)枚举值:

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

It is better for type-safety to use: 最好使用类型安全性:

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

because (A | B) is not one of your enum values. 因为(A | B)不是您的枚举值之一。

No, you don't have to use an array or a vector, but what you do need is bitwise comparisons. 不,您不必使用数组或向量,但是您需要做的是按位比较。

The first step is to set the numerical value of each flag an exponential value of 2 (ex - 1,2,4,8,16,32,64,etc...), so in binary it would look like 0001,0010,0100,1000 and so forth. 第一步是将每个标志的数值设置为2的指数值(例如-1,2,4,8,16,32,64等),因此在二进制形式中看起来像0001,0010 ,0100,1000等。

Now, to set or remove a flag, you need to either add it to the Flag variable, or remove it. 现在,要设置或删除标志,您需要将其添加到Flag变量中,或将其删除。 An example of checking for flags would like this: 一个检查标志的示例如下:

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

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

If foo is your bitflag, you can set A on foo by doing: 如果foo是您的位标记,则可以通过以下操作在foo上设置A:

foo |= A

Unset A on foo by doing: 通过执行以下操作来取消对foo的A:

foo &= (~A)

And check if A is set on foo by checking if this expression is true 并通过检查此表达式是否为真来检查是否对foo设置了A

(foo & A) == A

But you will have to make sure that the values of A,B,C,D are set up right (0x01, 0x02, ... ) 但是您必须确保正确设置A,B,C,D的值(0x01,0x02,...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM