C++ 包装枚举类型

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值