开发者

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?

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:

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.


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.

Now, to set or remove a flag, you need to either add it to the Flag variable, or remove it. 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 |= A

Unset A on foo by doing:

foo &= (~A)

And check if A is set on foo by checking if this expression is true

(foo & A) == A

But you will have to make sure that the values of A,B,C,D are set up right (0x01, 0x02, ... )

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜