c++运行时类型识别(rtti)

一个简单运行时类型识别

namespace rtti_ex {

	/*
	 *	类型信息基类
	 */
	class i_type_info {
	public:
		// 判断是否是指定类型
		bool is(const char* _name) const { return name() == _name; }
		template<class T> bool is() const { return is(T::name()); }

		// 判断是否是派生类型
		bool is_kind_of(const char* _name) const { return on_is_kind_of(_name); }
		template<class T> bool is_kind_of() const { return is_kind_of(T::name()); }

	protected:
		virtual bool on_is_kind_of(const char* name) const = 0;
		virtual const std::string& name() const = 0;
	};


	/**	类型信息
	 *	@_This	当前类
	 *	@_Base	基类
	 *	@_name_	返回当前类名称的函数
	 */
	template<class _This, class _Base, const char*(*_name_)()>
	class type_info : public _Base::type_info_t {
	public:
		type_info() : _name(_name_()) {}

	protected:
		virtual bool on_is_kind_of(const char* name) const {
			if (_name == name) {
				return true;
			}
			return _Base::type_info_t::on_is_kind_of(name);
		}
		virtual const std::string& name() const { return _name; };

	private:
		const std::string _name;
	};

	/**	偏特化,最开始的基类类型(即没有继承的类)
	 *	
	 */
	template<class _This, const char*(*_name_)()>
	class type_info<_This, void, _name_> : public i_type_info{
	public:
		type_info() : _name(_name_()) {}
	protected:
		virtual bool on_is_kind_of(const char* name) const {
			if (_name == name) {
				return true;
			}
			return false;
		}
		virtual const std::string& name() const { return _name; };
	private:
		const std::string _name;
	};

}


#define REGIST_INFO_CLASS(ThisClass, BaseClass) \
public: \
	static const char* name() { return #ThisClass; }\
	typedef rtti_ex::type_info<ThisClass, BaseClass, name> type_info_t; \
	virtual const rtti_ex::i_type_info& getinfo() { \
	static type_info_t* s_info = nullptr; \
		if (!s_info) { \
			type_info_t* p = new type_info_t(); \
			s_info = p; \
		} \
		return *s_info; \
	}

测试:

class A {
	REGIST_INFO_CLASS(A, void)
};



class B : public A {
	REGIST_INFO_CLASS(B, A)
};


class C : public B{
	REGIST_INFO_CLASS(C, B)
};

	C c;

	A* a = &c;
	bool b;

	b = a->getinfo().is<A>();
	b = a->getinfo().is<B>();
	b = a->getinfo().is<C>();

	b = a->getinfo().is_kind_of<A>();
	b = a->getinfo().is_kind_of<B>();
	b = a->getinfo().is_kind_of<C>();



posted on 2015-05-31 14:13  dchao  阅读(266)  评论(0编辑  收藏  举报

导航