I’m trying to create a small set of classes implementing a “safe flag” pattern, which would allow only predefined values to be OR-ed together. I’ve came up with something like that:
class MyClass;
class CreateFlag
{
friend class MyClass;
private:
int value;
CreateFlag(int newValue)
{
value = newValue;
}
public:
CreateFlag operator | (const CreateFlag & right) const
{
int newValue = value | right.value;
return CreateFlag(newValue);
}
CreateFlag(const CreateFlag && flag)
{
value = flag.value;
}
CreateFlag(const CreateFlag & flag)
{
value = flag.value;
}
static const CreateFlag Flag1;
static const CreateFlag Flag2;
static const CreateFlag Flag4;
};
const CreateFlag CreateFlag::Flag1 = CreateFlag(1);
const CreateFlag CreateFlag::Flag2 = CreateFlag(2);
const CreateFlag CreateFlag::Flag4 = CreateFlag(4);
class MyClass
{
public:
static void DisplayFlag(CreateFlag flag)
{
printf("Flag value: %d\n", flag.value);
}
};
int main(int argc, char * argv)
{
MyClass::DisplayFlag(CreateFlag::Flag1 | CreateFlag::Flag2);
getchar();
}
The problem is, that CreateFlag has a private ctor (what is intentional), so there is no way to specify the values of CreateFlag’s static fields and the above code does not compile.
A way to bypass this restriction is to change static fields into static methods returning an instance of CreateFlag, but that’s a dirty solution, as you would have to call the metod like:
MyClass::DisplayFlag(CreateFlag::Flag1() | CreateFlag::Flag2());
Is there a direct solution? If it changes anything, the flag definitions may be as well moved to the MyClass class.
I know also, that C++11 supports in-place initialization of static fields, but unfortunatelly VC++10 doesn’t support this construct yet…
Edit I’ve modified the code, such that anyone can copy it and use, it compiles now and works as intended to.
The above code doesn’t compile, but I think that it’s not compiling for reasons beyond what you’re expecting. Specifically, the compile error is in this line:
The reason is that
DisplayFlagtakes itsCreateFlagargument by value, and you’ve marked the copy constructor private.If you’re trying to ensure that people can’t OR together invalid values, I don’t think you need the copy constructor to be private. Making copies of
CreateFlags that you know are valid doesn’t allow clients to do anything that they previously couldn’t do. If you omit the definition of the copy constructor and just let C++’s default copy support work for you, you should be just fine.The lines that you’ve indicated as causing the error don’t seem to cause any problems. It compiles just fine once you remove the copy constructor.
Hope this helps!