C++的枚举类型与C中的枚举类型基本是一样的,它可与int类型隐式转换。但是并不等价于int类型,关于这部分的详细介绍请参考:《C++ 枚举类型的思考》
要对枚举类型进行检查必须在编译阶段想办法实现,一旦进入运行阶段枚举值就会被用整数来代替,但不一定是int类型,有可能是char、short等。
今天我想说的是,在C++中怎样来包装枚举类型让我们使用起来像用强类型一样安全。起始以下代码也不是本人发明的,而是从一个开源项目的源代码中发现的。将其摘抄出来做个笔记以便复习查看,首先是要写一个包装类,具体代码如下:
template<typename EnumValue>
class EnumWrapper
{
public:
typedef EnumValue EnumType;
EnumWrapper()
:mIsValid(false),
mValue()
{
}
EnumWrapper(const EnumValue& value)
:mIsValid(true),
mValue(value)
{
}
~EnumWrapper()
{}
bool isValid() const
{
return mIsValid;
}
operator EnumValue() const
{
if (mIsValid)
{
return mValue;
}
else
{
return static_cast<EnumValue>(-1);
}
}
bool operator==(const EnumWrapper& rhs) const
{
return ((mIsValid && rhs.mIsValid && mValue==rhs.mValue) || (!mIsValid && !rhs.mIsValid));
}
bool operator==(const EnumValue& enumVal) const
{
return (mIsValid && mValue == enumVal);
}
bool operator!=(const EnumWrapper& rhs) const
{
return !(operator==(rhs));
}
bool operator!=(const EnumValue& enumVal) const
{
return !(operator==(enumVal));
}
bool operator<(const EnumWrapper& rhs) const
{
if (mIsValid)
{
if (rhs.mIsValid)
{
return mValue<rhs.mValue;
}
else
{
return true; //有效<无效==true
}
}
else
{
if (rhs.mIsValid)
{
return false; //无效>有效
}
else
{
return false;
}
}
}
bool operator<(const EnumValue& enumVal) const
{
if (mIsValid)
{
return mValue < enumVal;
}
else
{
return false;
}
}
bool operator<=(const EnumWrapper& rhs) const
{
return operator<(rhs) || operator==(rhs);
}
bool operator<=(const EnumValue& enumVal) const
{
return operator<(enumVal) || operator==(enumVal);
}
bool operator>(const EnumWrapper& rhs) const
{
return !(operator<=(rhs));
}
bool operator>(const EnumValue& enumVal) const
{
return !(operator<=(enumVal));
}
bool operator>=(const EnumWrapper& rhs) const
{
return !(operator<(rhs));
}
bool operator>=(const EnumValue& enumVal) const
{
return !(operator<(enumVal));
}
private:
bool mIsValid; //标记此类的对象是否可用
EnumValue mValue; //存储枚举的实际值
};
template <typename T>
bool operator!=(const T& lhs, const EnumWrapper<T>& rhs)
{
return EnumWrapper<T>(lhs) != rhs;
}
template<typename T>
bool operator==(const T& lhs,const EnumWrapper<T>& rhs)
{
return EnumWrapper<T>(lhs)==rhs;
}
template <typename T>
bool operator<(const T& lhs, const EnumWrapper<T>& rhs)
{
return EnumWrapper<T>(lhs) < rhs;
}
template <typename T>
bool operator<=(const T& lhs, const EnumWrapper<T>& rhs)
{
return EnumWrapper<T>(lhs) <= rhs;
}
template <typename T>
bool operator>(const T& lhs, const EnumWrapper<T>& rhs)
{
return EnumWrapper<T>(lhs) > rhs;
}
template <typename T>
bool operator>=(const T& lhs, const EnumWrapper<T>& rhs)
{
return EnumWrapper<T>(lhs) >= rhs;
}
#endif
具体用法如下:
enum EON {
One,
Two,
Three,
Four
};
typedef EnumWrapper<EON> TEStype;
enum ETW {
Fire,
Six
};
typedef EnumWrapper<ETW> TEWtype;
int main(int argc, _TCHAR* argv[])
{
TEStype tsp;
bool isv=tsp.isValid(); //因为每赋值,所以isv为false
tsp=Four;
isv=tsp.isValid(); //已经赋值,所以isv为true
tsp=4; //编译错误,因为类型不对
tsp=Fire; //编译错误,不能将ETW类型的变量赋值给TEStype类型
TEWtype wsp;
wsp=tsp; //编译错误,类型不符
return 0;
}