一个简单的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;
}




posted on 2011-11-30 18:22  几百人有爱  阅读(279)  评论(0编辑  收藏  举报