一个简单运行时类型识别
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>();