您的位置:首页 > 编程语言 > C语言/C++

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

2011-11-30 18:22 411 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: