zoukankan      html  css  js  c++  java
  • 一个简单的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;
    }




  • 相关阅读:
    51 Nod 1068 Bash游戏v3
    51 Nod Bash 游戏v2
    51 Nod 1073 约瑟夫环
    UVA 12063 Zeros and ones 一道需要好好体会的好题
    51 Nod 1161 Partial sums
    2018中国大学生程序设计竞赛
    UVA 11971 Polygon
    UVA 10900 So do you want to be a 2^n-aire?
    UVA 11346 Possibility
    python with as 的用法
  • 原文地址:https://www.cnblogs.com/iapp/p/3631842.html
Copyright © 2011-2022 走看看