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, ... )
精彩评论