• 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>();



  • 相关阅读:
    测试爬虫
    流式大数据处理的三种框架:Storm,Spark和Samza
    redo日志
    HTTP协议之chunk编码(分块传输编码
    QWidget 实现 打破布局 或者 当前窗体内的 弹窗 (借助伪造实现)
    How to use kingshard building a MySQL cluster
    转载: Qt 学习之路 2归档
    Python与机器人技术
    Nginx配置正向代理
    使用Chrony配置 NTP
  • 原文地址:https://www.cnblogs.com/dongc/p/5225104.html
Copyright © 2020-2023  润新知