不互斥的枚举

Enum枚举类中实现:一个枚举组是否包含其中的几个枚举对象

假设我有一个枚举类,这个枚举类用来修饰一个类的各种属性,枚举并不互斥,可以协同修饰一个类。或者说这个枚举用于表明这个类的各个状态。可以将这个状态标记为OnOff

假设我有一个枚举Buff:

public:
	enum Buff
	{
		AttackUp = 0x01,//攻击力上升buff
		HurtReduction = 0x02,//伤害减免buff
		GoldUp = 0x03,//金币增加
	}

以上的枚举代表了三种不同的增益,用16进制int类型表示。

定义了一个枚举组Buffs

然后绑定Buffs和Buff,预定义为: DECLARE_FLAGS(Buffs, Buff);

枚举对象本质是int类型,因此这个Buffs类需要实现几个int的逻辑运算符号重载。

#ifndef CORE_FLAGS_H
#define CORE_FLAGS_H
#include "core/global.hpp"
#include "qtypeinfo.h"
#include "dtypetraits.h

class DFlag
{
	int i;
public:
	inline DFlag(int ai) : i(ai) {}
	inline DFlag(uint ai) : i(int(ai)) {}
	inline DFlag(short ai) : i(int(ai)) {}
	inline DFlag(ushort ai) : i(int(uint(ai))) {}
	inline operator int() const
	{
		return i;
	}
	inline operator uint() const
	{
		return uint(i);
	}
};
DAN_DECLARE_TYPEINFO(DFlag, D_PRIMITIVE_TYPE);

class IncompatibleFlag
{
	int i;
public:
	inline explicit IncompatibleFlag(int i);
	inline operator int() const
	{
		return i;
	}
};


inline IncompatibleFlag::IncompatibleFlag(int ai) : i(ai) {}

template<typename EnumType>
class LOCALAPI DFlags
{
public:

	typedef EnumType enum_type;

	typedef int Int;
#ifndef SWIG
	typedef int(*Zero);
	inline DFlags(Zero = 0) : i(0) {}
#endif
	inline DFlags(EnumType f) : i(Int(f)) {}

	inline DFlags(DFlag f) : i(f) {}

	inline DFlags &operator&=(int mask)
	{
		i &= mask;
		return *this;
	}
	inline DFlags &operator&=(uint mask)
	{
		i &= mask;
		return *this;
	}
	inline DFlags &operator&=(EnumType mask)
	{
		i &= Int(mask);
		return *this;
	}
	inline DFlags &operator|=(DFlags f)
	{
		i |= f.i;
		return *this;
	}
	inline DFlags &operator|=(EnumType f)
	{
		i |= Int(f);
		return *this;
	}
	inline DFlags &operator^=(DFlags f)
	{
		i ^= f.i;
		return *this;
	}
	inline DFlags &operator^=(EnumType f)
	{
		i ^= Int(f);
		return *this;
	}

	inline operator Int() const
	{
		return i;
	}
	inline int toInt() const
	{
		return i;
	}
	inline DFlags operator|(DFlags f) const
	{
		return DFlags(DFlag(i | f.i));
	}
	inline DFlags operator|(EnumType f) const
	{
		return DFlags(DFlag(i | Int(f)));
	}
	inline DFlags operator^(DFlags f) const
	{
		return DFlags(DFlag(i ^ f.i));
	}
	inline DFlags operator^(EnumType f) const
	{
		return DFlags(DFlag(i ^ Int(f)));
	}
	inline DFlags operator&(int mask) const
	{
		return DFlags(DFlag(i & mask));
	}
	inline DFlags operator&(uint mask) const
	{
		return DFlags(DFlag(i & mask));
	}
	inline DFlags operator&(EnumType f) const
	{
		return DFlags(DFlag(i & Int(f)));
	}
	inline DFlags operator~() const
	{
		return DFlags(DFlag(~i));
	}

	inline bool operator!() const
	{
		return !i;
	}

	inline bool testFlag(EnumType f) const
	{
		return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f));
	}
private:
	Int i;
};


#define DECLARE_FLAGS(Flags, Enum)\
typedef DFlags<Enum> Flags;

#endif

使用方法如下

private:
	Buffs _my_buff;
public:
	void setBuffStatus(Buff buff, bool on /*= true*/)
	{
		if (on)
		{
			_my_buff = _my_buff | buff;
		}
		else {
			_my_buff = _my_buff & ~buff;
		}
	}
	
	bool checkBuffStatus(Buff buff) const
	{
		return  _my_buff & buff;
	}

通过或与非运算,能检测到当前枚举组中是否存在指定枚举对象。
或者换一种说法,能检测到指定枚举对象是否处于激活状态。

猜你喜欢

转载自blog.csdn.net/loveyou388i/article/details/83583694