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; }