我正在尝试创建一组实现“安全标志”模式的类,这样只允许将预定义值一起进行OR运算。我想出了类似的东西:
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();
}
问题是,CreateFlag有一个私有ctor(故意是什么),所以没有办法指定CreateFlag的静态字段的值,上面的代码也没有编译。
绕过此限制的一种方法是将静态字段更改为返回CreateFlag实例的静态方法,但这是一个肮脏的解决方案,因为您必须调用metod,如:
MyClass::DisplayFlag(CreateFlag::Flag1() | CreateFlag::Flag2());
有直接解决方案吗?如果它改变了什么,标志定义也可以移动到MyClass类。
我也知道,C ++ 11支持静态字段的就地初始化,但不幸的是VC ++ 10还不支持这种构造......
编辑我修改了代码,以便任何人都可以复制和使用,现在可以编译并按预期工作。
答案 0 :(得分:2)
上面的代码没有编译,但我认为它不是出于超出您期望的原因进行编译。具体来说,编译错误在这一行:
MyClass::DisplayFlag(CreateFlag::Flag1 | CreateFlag::Flag2);
原因是DisplayFlag
按值获取CreateFlag
参数,并且您已将复制构造函数标记为私有。
如果您正在尝试确保人们无法将无效值组合在一起,我认为您不需要将复制构造函数设置为私有。制作您知道的有效CreateFlag
的副本不允许客户做任何他们以前无法做的事情。如果省略了复制构造函数的定义,只是让C ++的默认复制支持对你有用,那么你应该没问题。
您指出导致错误的行似乎不会导致任何问题。删除复制构造函数后, It compiles just fine 。
希望这有帮助!