views:

100

answers:

4

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?
+1  A: 

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.

Heath Hunnicutt
A: 

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
}
Shawn B
+2  A: 
// 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;
}
sbi
Thanks, and would there be a way of (un)setting multiple flags at once?
sub
Add ResetFlag(Flags flag) { theFlags } and pass Flags.A|Flags.B for example.
Hans Passant
@nobugz: Thanks, I'll add this to the answer, if you don't mind. (Oh, but `Flags.A` isn't C++ syntax.)
sbi
@sub: look at the STL `bitset` data structure. This should be helpful when dealing with a number of flags (bits) that may not be an even multiple of the processor's native data type.
Thomas Matthews
A: 

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, ... )

abenthy