zoukankan      html  css  js  c++  java
  • 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>();



  • 相关阅读:
    建立自己的开发知识库?分享制作电子书的经验
    海量Office文档搜索
    为什么要检测数据库连接是否可用
    多年的.NET开发,也只学会了这么几招
    总结一下ERP .NET程序员必须掌握的.NET技术
    菜单设计器(Menu Designer)及其B/S,C/S双重实现(B/S开源)
    软件公司为什么要加密源代码
    .NET开发中经常用到的扩展方法
    在Win8 Mertro 中使用SQLite
    SQLite
  • 原文地址:https://www.cnblogs.com/dongc/p/5225104.html
Copyright © 2011-2022 走看看