http://blog.youkuaiyun.com/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;
}