我们知道C++的enum为兼容C,也继承了其缺点,其成员为全局作用域。
比如下面的例子,编译的时候Count就被认为重复定义了:
enum type1 {Bone, Fat, Muscle, Count};
enum type2 {Avg, Med, Var, Count};
然后我们知道C++11出来个enum class,改善了上述问题,并使枚举变成强数据类型。
在一般情况,这种做法都是很不错的。但有时候我们还是希望enum变量可以和int类型互转。尤其是程序会反复调用时,我们不希望引入独立的函数去转换,毕竟这样程序的易用性将在一定程度被降低。
比如这样,那别人用这个程序还得调这么长一段,很不优雅:
enum class EnumType {Bone, Fat, Muscle, Count};
int EnumTypeToInt(EnumType enum)
{
...
}
EnumType IntToEnumType(int type)
{
...
}
那我们既想要enum的隐形转换,又想要enum class的可控的作用域,甚至还想为其封装一些方法,怎么办呢?
struct ValueOrderEnum {
virtual void NOINSTANCE() = 0; //避免用户误用此类
enum Type { Avg, Med, Var, Count };
};
using ValueOrder = ValueOrderEnum::Type;
//那么,我们就可以这样写一个类,是不是优雅多了
class SwitchManager
{
public:
void SetOrderValue(ValueOrder order, bool value) //利用int不能隐形转换为enum,避免过界
{
mSwitcValue[order] = value; //enum可以隐式转换为int
}
bool GetAverageValue()
{
return mSwitcValue[ValueOrder::Avg];
}
int SearchValue(bool targetValue)
{
for(int index = 0; index < ValueOrder::Count; index++) //当我们增加枚举时,
{
if(mSwitcValue[index] == targetValue)
{
return index;
}
}
return 0;
}
private:
bool mSwitcValue[ValueOrder::Count];
};
上面的ValueOrderEnum其实还可以扩展一些方法。这种写法一般用在索引比较频繁的时候,还是挺有用的。
这篇文章发了三年了,对于下面的问题还是回复一下吧,:
第一条说,namespace可以解决问题,笑了,那你想想文中“甚至还想为其封装一些方法”这句话啥意思,然后为啥要用下面这句话。
virtual void NOINSTANCE() = 0; //避免用户误用此类
第二条说,static_cast转一下就行,原文“不希望引入独立的函数去转换”表述有点问题,其实我当时希望的时不要任何转换函数,全部隐式转换,好看点。