• 一个简单的C++的RTTI实现


    http://blog.csdn.net/wzq9706/article/details/7028105


    前两天,跟刘总讨论工厂模式时,从其金口(^-^)中得知有反射和RTTI这两种模式,这两天看了一些资料,云里雾里的,实濺出真知,今天决定试一试,虽然目前还没搞清反射的具体情况,

    从网络上看的很多资料中,有用到类似"DECARE_DYNAMIC_CLASS", "IMPLEMENT_DYNAMIC_CLASS"宏,似曾相识啊,以前做项目常常用到这些类似的宏,但以前是只知有其物,不知为何物,只会使用,但不知道它的工作机制是什么,于是乎下午就拿点时间研究了一下,刚好手头有"wxWidgets"的库(MFC很少用到),就拿它开刀吧,经过一翻的"右键→转到定义"之后,终于点明白是怎么一回事了,于是就依样画胡地实现了一个简单的RTTI,.....欢迎拍砖:


    回家用vs2008发现地址冲突, 把_classTable改成指针后,在vs2008和2010编译正常,望有大侠指点,看看现在的代码有没有什么问题

    首先是最主要的部分

    myClassInfo

    声明

        #ifndef __myRtti__H__  
        #define __myRtti__H__  
          
        #include <map>  
        #include <string>  
          
        class myObject;  
          
        typedef myObject* (*createCallback)(void);  
          
        // 类信息类,用于保存和获到类信息,通过字符串(class name)动态生成相应的类对象  
        class myClassInfo  
        {  
        public:  
          
            friend myObject* myClassInfo::createDynamicObject(const char* name);  
          
            // 构造函数  
            myClassInfo(const char* className, const myClassInfo* baseInfo, int size, createCallback fun);  
          
            // 析构函数  
            virtual ~myClassInfo();  
          
            // 跟据给定的字符串创建对象  
            static myObject* createDynamicObject(const char* name);  
          
            // 是否可以动态生成  
            bool IsDynamic() const   
            { return NULL != _createFun; }  
          
            // 给定的类信息是否是本类或者本类的所有父类中的任意一个  
            bool IsKindOf(const myClassInfo *info) const  
            {  
                return info != 0 && ( info == this || ( _baseInfo && _baseInfo->IsKindOf(info) ) );  
            }  
              
            // 获得类名  
            const char* getClassName() const  
            { return _className; }  
          
            // 获得父类名  
            const char* getBaseClassName() const  
            { return _baseInfo ? _baseInfo->getClassName() : NULL; }  
          
            // 获得得父类信息  
            const myClassInfo* getBaseClass() const   
            { return _baseInfo; }  
          
            // 获得类的大小  
            int getClassSize() const  
            { return _classSize; }  
          
            // 跟据_createFun创建类对象  
            myObject* create();  
          
        protected:  
          
            // 注册类信息,将类信息(自已)保存在_classTable中  
            void Register();  
          
            // 反注册类信息,将类信息(自已)从_classTable中删除  
            void UnRegister();  
          
        private:  
          
            typedef std::map<std::string, myClassInfo*>  ClassTable;  
          
            const char*         _className;         // 类名  
            int                 _classSize;         // 类大小  
            const myClassInfo*  _baseInfo;          // 父类信息  
            createCallback      _createFun;         // 类构造函数指针  
            static ClassTable*  _classTable;        // 类映射表  
        };  
          
        // 以下的宏就不解释了,自已看, 一个放在类声明(一般在.h文件)中, 一个放在类声明外(一般在.cpp中)  
        // DECLARE_DYNAMIC_CLASS中的参数暂时没用  
          
        // ====================================================  
        // Dynamic class macros   
        // ====================================================  
        #define DECLARE_DYNAMIC_CLASS(name) \
    public: \
    	static myClassInfo  _classInfo; \
    	virtual myClassInfo* getClassInfo() const; \
    	static  myObject* createObject();                 
          
        // ====================================================  
        // Dynamic class macros  
        // ====================================================  
        #define IMPLEMENT_DYNAMIC_CLASS(name, basename) \
    	myClassInfo name::_classInfo(#name,  &basename::_classInfo, (int)sizeof(name), name::createObject); \
            myClassInfo* name::getClassInfo() const \
    		{ return &name::_classInfo; }\
    										\
            myObject* name::createObject() \
    		{ return new name; }  
          
        #endif  



    实现:

        #include "myRtti.h"  
          
        myClassInfo::ClassTable* myClassInfo::_classTable = NULL;  
          
        // ==============================================================  
        myClassInfo::myClassInfo(const char* className, const myClassInfo* baseInfo, int size, createCallback fun)  
        : _className(className)  
        , _baseInfo(baseInfo)  
        , _classSize(size)  
        , _createFun(fun)  
        {  
            Register();  
        }  
          
        // ==============================================================  
        myClassInfo::~myClassInfo()  
        {  
            UnRegister();  
        }  
          
        // ==============================================================  
        myObject* myClassInfo::createDynamicObject(const char* name)  
        {  
            ClassTable::iterator pos = _classTable->find(name);  
            if (pos == _classTable->end())  
            {  
                throw("Not found the class of this name in rtti table");  
            }  
            return pos->second->create();  
        }  
          
        // ==============================================================  
        void myClassInfo::Register()  
        {  
    		if (NULL == _classTable)
    		{
    			_classTable = new ClassTable;
    		}
    		
    		ClassTable::iterator pos = _classTable->find(_className);  
            if (pos != _classTable->end())  
            {  
                throw("The class of this name is already in rtti table");  
            }  
            (*_classTable)[_className] = this;  
        }  
          
        // ==============================================================  
        void myClassInfo::UnRegister()  
        {  
    		if (NULL != _classTable)
    		{
    			_classTable->erase(_classTable->find(_className)); 
    			if (_classTable->size() == 0)
    			{
    				delete _classTable;
    				_classTable = NULL;
    			}
    			
    		}     
        }  
          
        // ==============================================================  
        myObject* myClassInfo::create()  
        {  
            return _createFun ? (*_createFun)() : NULL;  
        }  


    然后就是对象的基类

    myObject

    声明

    #ifndef __myObject__H__
    #define __myObject__H__
    
    #include "myRtti.h"
    
    // 对象基类
    class myObject
    {
    	DECLARE_DYNAMIC_CLASS(myObject)		// 动态地声明一些用于RTTI的必要的成员
    public:
    
    	myObject(){}
    
    	virtual ~myObject(){}
    };
    
    #endif

    实现

    #include "myObject.h"
    
    myClassInfo myObject::_classInfo("myObject", NULL,  sizeof(myObject), myObject::createObject); 
    
    myClassInfo* myObject::getClassInfo() const
    { 
    	return &myObject::_classInfo; 
    }
    
    myObject* myObject::createObject()						
    { return new myObject; }
    

    测试代码

    #include "myObject.h"
    
    // 派生出myObject的子类
    class TestClass : public myObject
    {
    	DECLARE_DYNAMIC_CLASS(TestClass)	// 动态地声明一些用于RTTI的成员
    public:
    	void print()
    	{
    		printf("Class Name is: %s \n", _classInfo.getClassName());
    	}
    };
    
    IMPLEMENT_DYNAMIC_CLASS(TestClass, myObject)	// 动态地实现一些用于RTTI的成员
    
    
    // 测试的主函数
    int main()
    {
    	TestClass* t = (TestClass*)myClassInfo::createDynamicObject("TestClass");
    	t->print();
    	return 0;
    }




  • 相关阅读:
    课堂作业
    大道至简读后感
    读《大道至简》有感
    大道至简第四章-流于形式的沟通
    Java课堂动手动脑-截图集锦
    Java动手动脑课后作业1-求创建对象个数
    Java-消息框显示两整数加减乘除
    JAVA-实践问题
    Java-整数相加求和
    大道至简-是懒人造就了方法
  • 原文地址:https://www.cnblogs.com/iapp/p/3631842.html
Copyright © 2020-2023  润新知