一个简单的RTTI实现
2015-03-06 10:45
169 查看
RTTI是"Runtime Type Information"的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.
最近在写的一些东西,不想使用MFC之类的框架,但是却在很多地方需要根据名称确定指针的转换类型或者利用抽象工厂生产抽象的类对象指针...
我很不喜欢不容易维护且难看的"switch case",而C++本身的RTTI功能又显得很单薄...看来只有自己写一个C++的RTTI实现了.
RTTI.h:
[cpp] view
plaincopy
//////////////////////////////////////////////////////////////////
// RTTI - RTTI 支持
//
// Author: 木头云
// Blog: http://hi.baidu.com/markl22222
// E-Mail: mark.lonr@tom.com
// Version: 1.0.1001.1823
//////////////////////////////////////////////////////////////////
#ifndef __STDCPX_RTTI_H__
#define __STDCPX_RTTI_H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//////////////////////////////////////////////////////////////////
// RTTI 起始类声明
class CBaseObj;
//////////////////////////////////////////////////////////////////
// type_id 自增量
extern int TypeInfoOrder;
// 类型信息结构
struct TypeInfo
{
typedef CBaseObj* (*pfn_dc)(GCAlloc& gc);
LPTSTR className;
int type_id;
TypeInfo* pBaseClass;
pfn_dc m_pfnCreateObject; // NULL => abstract class
CBaseObj* CreateObject(GCAlloc& gc)
{
if( m_pfnCreateObject == NULL ) return NULL;
return (*m_pfnCreateObject)(gc);
}
bool operator == (const TypeInfo& info)
{
return this == &info;
}
bool operator != (const TypeInfo& info)
{
return this != &info;
}
};
//////////////////////////////////////////////////////////////////
// 向工厂注册 TypeInfo 指针
#define REGISTER_TYPEINFO(key, inf) /
CTypeInfoFactory::GetInstance()->RegisterTypeInfo(key, inf)
// 从工厂得到 TypeInfo 指针
#define GET_TYPEINFO(key) /
CTypeInfoFactory::GetInstance()->GetTypeInfo(key)
// TypeInfo 指针单例工厂
class CTypeInfoFactory sealed
{
private:
typedef Map<tstring, TypeInfo*> key_map;
private:
key_map dc_funcs;
private:
CTypeInfoFactory(GCAlloc& gc) : dc_funcs(gc) {}
public:
// 获得工厂单例
static CTypeInfoFactory* GetInstance()
{
// 仅用于RTTI时不需要考虑线程同步问题
// 为了提高效率, 此处不加线程同步锁
static GCAlloc gc;
static CTypeInfoFactory instance(gc);
return &instance;
}
// 向工厂注册一个类名
bool RegisterTypeInfo(LPCTSTR c_key, TypeInfo* inf)
{
if( c_key == NULL ) return false;
tstring key(c_key);
if( dc_funcs.find(key) == dc_funcs.end() )
{
dc_funcs.insert( key_map::value_type(key, inf) );
return true;
}
else
return false;
}
// 从工厂获得一个 TypeInfo
TypeInfo* GetTypeInfo(LPCTSTR c_key)
{
if( c_key == NULL ) return NULL;
tstring key(c_key);
if( dc_funcs.find(key) == dc_funcs.end() )
return NULL;
else
return dc_funcs[key];
}
};
//////////////////////////////////////////////////////////////////
// Base Typedef 宏定义
#define DEF_BASETYPE(base_name) /
public: /
typedef base_name Base;
//////////////////////////////////////////////////////////////////
// TYPEINFO 类型信息宏定义
#define TYPEINFO_OF_CLS(cls_name) (cls_name::GetTypeInfoClass())
#define TYPEINFO_OF_OBJ(obj_name) (obj_name.GetTypeInfo())
#define TYPEINFO_OF_PTR(ptr_name) (ptr_name->GetTypeInfo())
#define TYPEINFO_MEMBER(cls_name) rttiTypeInfo
//////////////////////////////////////////////////////////////////
// 类的 RTTI 宏定义
#define DECLARE_TYPEINFO_CLS(cls_name, base_name) /
DEF_BASETYPE(base_name) /
public: /
virtual int GetTypeID() { return TYPEINFO_MEMBER(cls_name).type_id; } /
virtual LPCTSTR GetTypeName() { return TYPEINFO_MEMBER(cls_name).className; } /
virtual TypeInfo& GetTypeInfo() { return TYPEINFO_MEMBER(cls_name); } /
static TypeInfo& GetTypeInfoClass() { return TYPEINFO_MEMBER(cls_name); } /
private: /
static TypeInfo TYPEINFO_MEMBER(cls_name);
#define DECLARE_TYPEINFO_NULL(cls_name) /
public: /
virtual int GetTypeID() { return TYPEINFO_MEMBER(cls_name).type_id; } /
virtual LPCTSTR GetTypeName() { return TYPEINFO_MEMBER(cls_name).className; } /
virtual TypeInfo& GetTypeInfo() { return TYPEINFO_MEMBER(cls_name); } /
static TypeInfo& GetTypeInfoClass() { return TYPEINFO_MEMBER(cls_name); } /
private: /
static TypeInfo TYPEINFO_MEMBER(cls_name); /
public: /
bool IsKindOf(TypeInfo& cls);
// dynamically typeinfo
#define DECLARE_DYNAMIC_CLS(cls_name, base_name) /
DECLARE_TYPEINFO_CLS(cls_name, base_name)
#define DECLARE_DYNAMIC_NULL(cls_name) /
DECLARE_TYPEINFO_NULL(cls_name)
// dynamically constructable
#define DECLARE_DYNCREATE_CLS(cls_name, base_name) /
DECLARE_DYNAMIC_CLS(cls_name, base_name) /
public: /
static CBaseObj* CreateObject(GCAlloc& gc); /
private: /
static bool m_bRegSuccess;
#define DECLARE_DYNCREATE_NULL(cls_name) /
DECLARE_DYNAMIC_NULL(cls_name) /
public: /
static CBaseObj* CreateObject(GCAlloc& gc); /
private: /
static bool m_bRegSuccess;
/////////////////////////////////
#define IMPLEMENT_TYPEINFO_CLS(cls_name, base_name, pfn_new) /
TypeInfo cls_name::TYPEINFO_MEMBER(cls_name) = /
{ _T(#cls_name), TypeInfoOrder++, &(base_name::GetTypeInfoClass()), pfn_new };
#define IMPLEMENT_TYPEINFO_NULL(cls_name, pfn_new) /
TypeInfo cls_name::TYPEINFO_MEMBER(cls_name) = /
{ _T(#cls_name), TypeInfoOrder++, NULL, pfn_new }; /
bool cls_name::IsKindOf(TypeInfo& cls) /
{ /
TypeInfo* p = &(this->GetTypeInfo()); /
while( p != NULL ) /
{ /
if( p->type_id == cls.type_id ) /
return true; /
p = p->pBaseClass; /
} /
return false; /
}
// dynamically typeinfo
#define IMPLEMENT_DYNAMIC_CLS(cls_name, base_name) /
IMPLEMENT_TYPEINFO_CLS(cls_name, base_name, NULL)
#define IMPLEMENT_DYNAMIC_NULL(cls_name) /
IMPLEMENT_TYPEINFO_NULL(cls_name, NULL)
// dynamically constructable
#define IMPLEMENT_DYNCREATE_CLS(cls_name, base_name) /
IMPLEMENT_TYPEINFO_CLS(cls_name, base_name, cls_name::CreateObject) /
CBaseObj* cls_name::CreateObject(GCAlloc& gc) /
{ return /*new cls_name*/GC_NEW(gc, cls_name); } /
bool cls_name::m_bRegSuccess = /
REGISTER_TYPEINFO( _T(#cls_name), &(cls_name::TYPEINFO_MEMBER(cls_name)) );
#define IMPLEMENT_DYNCREATE_NULL(cls_name) /
IMPLEMENT_TYPEINFO_NULL(cls_name, cls_name::CreateObject) /
CBaseObj* cls_name::CreateObject(GCAlloc& gc) /
{ return /*new cls_name*/GC_NEW(gc, cls_name); } /
bool cls_name::m_bRegSuccess = /
REGISTER_TYPEINFO( _T(#cls_name), &(cls_name::TYPEINFO_MEMBER(cls_name)) );
//////////////////////////////////////////////////////////////////
// 动态指针转换宏定义
#define DYNAMIC_CAST(cls_name, object_ptr) /
dynamic_cast_t<cls_name>( TYPEINFO_OF_CLS(cls_name), object_ptr )
// 动态对象创建宏定义
#define DYNAMIC_CREATE(cls_name, key, gc) /
dynamic_create_t<cls_name>( key, gc )
//////////////////////////////////////////////////////////////////
// RTTI 起始类
class CBaseObj
{
DECLARE_DYNCREATE_NULL(CBaseObj)
};
//////////////////////////////////////////////////////////////////
// 动态指针转换函数模板
template <class T>
inline T* dynamic_cast_t(TypeInfo& cls, CBaseObj* ptr)
{
if( ptr )
return ptr->IsKindOf(cls) ? (T*)ptr : NULL;
else
return NULL;
}
// 动态对象创建函数
template <class T>
inline T* dynamic_create_t(LPCTSTR c_key, GCAlloc& gc)
{
if( c_key == NULL ) return NULL;
TypeInfo* inf = GET_TYPEINFO(c_key);
if( inf )
return DYNAMIC_CAST( T, inf->CreateObject(gc) );
else
return NULL;
}
//////////////////////////////////////////////////////////////////
#endif // __STDCPX_RTTI_H__
RTTI.cpp:
[cpp] view
plaincopy
#include "stdafx.h"
#ifndef __STDCPX_RTTI_H__
#include "detail//RTTI.h"
#endif
//////////////////////////////////////////////////////////////////
// type_id 自增量初始化
extern int TypeInfoOrder = 0;
// CBaseObj 成员定义
IMPLEMENT_DYNCREATE_NULL(CBaseObj)
在"struct TypeInfo"中我用到了许式伟的StdExt库,若要单独使用的话需要把"Map"改为"map",即使用stl的map完成同样的功能,并删除掉带有"GCAlloc"的语句.
此RTTI在使用上类似MFC的RTTI,所有需要用到RTTI功能的类必须继承自"class CBaseObj".
使用示例:
Show.h:
[cpp] view
plaincopy
class CShow : public CBaseObj
{
DECLARE_DYNAMIC_CLS(CShow, CBaseObj)
public:
CShow() {}
virtual ~CShow() {}
};
Show.cpp:
[cpp] view
plaincopy
IMPLEMENT_DYNAMIC_CLS(CShow, CBaseObj)
最近在写的一些东西,不想使用MFC之类的框架,但是却在很多地方需要根据名称确定指针的转换类型或者利用抽象工厂生产抽象的类对象指针...
我很不喜欢不容易维护且难看的"switch case",而C++本身的RTTI功能又显得很单薄...看来只有自己写一个C++的RTTI实现了.
RTTI.h:
[cpp] view
plaincopy
//////////////////////////////////////////////////////////////////
// RTTI - RTTI 支持
//
// Author: 木头云
// Blog: http://hi.baidu.com/markl22222
// E-Mail: mark.lonr@tom.com
// Version: 1.0.1001.1823
//////////////////////////////////////////////////////////////////
#ifndef __STDCPX_RTTI_H__
#define __STDCPX_RTTI_H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//////////////////////////////////////////////////////////////////
// RTTI 起始类声明
class CBaseObj;
//////////////////////////////////////////////////////////////////
// type_id 自增量
extern int TypeInfoOrder;
// 类型信息结构
struct TypeInfo
{
typedef CBaseObj* (*pfn_dc)(GCAlloc& gc);
LPTSTR className;
int type_id;
TypeInfo* pBaseClass;
pfn_dc m_pfnCreateObject; // NULL => abstract class
CBaseObj* CreateObject(GCAlloc& gc)
{
if( m_pfnCreateObject == NULL ) return NULL;
return (*m_pfnCreateObject)(gc);
}
bool operator == (const TypeInfo& info)
{
return this == &info;
}
bool operator != (const TypeInfo& info)
{
return this != &info;
}
};
//////////////////////////////////////////////////////////////////
// 向工厂注册 TypeInfo 指针
#define REGISTER_TYPEINFO(key, inf) /
CTypeInfoFactory::GetInstance()->RegisterTypeInfo(key, inf)
// 从工厂得到 TypeInfo 指针
#define GET_TYPEINFO(key) /
CTypeInfoFactory::GetInstance()->GetTypeInfo(key)
// TypeInfo 指针单例工厂
class CTypeInfoFactory sealed
{
private:
typedef Map<tstring, TypeInfo*> key_map;
private:
key_map dc_funcs;
private:
CTypeInfoFactory(GCAlloc& gc) : dc_funcs(gc) {}
public:
// 获得工厂单例
static CTypeInfoFactory* GetInstance()
{
// 仅用于RTTI时不需要考虑线程同步问题
// 为了提高效率, 此处不加线程同步锁
static GCAlloc gc;
static CTypeInfoFactory instance(gc);
return &instance;
}
// 向工厂注册一个类名
bool RegisterTypeInfo(LPCTSTR c_key, TypeInfo* inf)
{
if( c_key == NULL ) return false;
tstring key(c_key);
if( dc_funcs.find(key) == dc_funcs.end() )
{
dc_funcs.insert( key_map::value_type(key, inf) );
return true;
}
else
return false;
}
// 从工厂获得一个 TypeInfo
TypeInfo* GetTypeInfo(LPCTSTR c_key)
{
if( c_key == NULL ) return NULL;
tstring key(c_key);
if( dc_funcs.find(key) == dc_funcs.end() )
return NULL;
else
return dc_funcs[key];
}
};
//////////////////////////////////////////////////////////////////
// Base Typedef 宏定义
#define DEF_BASETYPE(base_name) /
public: /
typedef base_name Base;
//////////////////////////////////////////////////////////////////
// TYPEINFO 类型信息宏定义
#define TYPEINFO_OF_CLS(cls_name) (cls_name::GetTypeInfoClass())
#define TYPEINFO_OF_OBJ(obj_name) (obj_name.GetTypeInfo())
#define TYPEINFO_OF_PTR(ptr_name) (ptr_name->GetTypeInfo())
#define TYPEINFO_MEMBER(cls_name) rttiTypeInfo
//////////////////////////////////////////////////////////////////
// 类的 RTTI 宏定义
#define DECLARE_TYPEINFO_CLS(cls_name, base_name) /
DEF_BASETYPE(base_name) /
public: /
virtual int GetTypeID() { return TYPEINFO_MEMBER(cls_name).type_id; } /
virtual LPCTSTR GetTypeName() { return TYPEINFO_MEMBER(cls_name).className; } /
virtual TypeInfo& GetTypeInfo() { return TYPEINFO_MEMBER(cls_name); } /
static TypeInfo& GetTypeInfoClass() { return TYPEINFO_MEMBER(cls_name); } /
private: /
static TypeInfo TYPEINFO_MEMBER(cls_name);
#define DECLARE_TYPEINFO_NULL(cls_name) /
public: /
virtual int GetTypeID() { return TYPEINFO_MEMBER(cls_name).type_id; } /
virtual LPCTSTR GetTypeName() { return TYPEINFO_MEMBER(cls_name).className; } /
virtual TypeInfo& GetTypeInfo() { return TYPEINFO_MEMBER(cls_name); } /
static TypeInfo& GetTypeInfoClass() { return TYPEINFO_MEMBER(cls_name); } /
private: /
static TypeInfo TYPEINFO_MEMBER(cls_name); /
public: /
bool IsKindOf(TypeInfo& cls);
// dynamically typeinfo
#define DECLARE_DYNAMIC_CLS(cls_name, base_name) /
DECLARE_TYPEINFO_CLS(cls_name, base_name)
#define DECLARE_DYNAMIC_NULL(cls_name) /
DECLARE_TYPEINFO_NULL(cls_name)
// dynamically constructable
#define DECLARE_DYNCREATE_CLS(cls_name, base_name) /
DECLARE_DYNAMIC_CLS(cls_name, base_name) /
public: /
static CBaseObj* CreateObject(GCAlloc& gc); /
private: /
static bool m_bRegSuccess;
#define DECLARE_DYNCREATE_NULL(cls_name) /
DECLARE_DYNAMIC_NULL(cls_name) /
public: /
static CBaseObj* CreateObject(GCAlloc& gc); /
private: /
static bool m_bRegSuccess;
/////////////////////////////////
#define IMPLEMENT_TYPEINFO_CLS(cls_name, base_name, pfn_new) /
TypeInfo cls_name::TYPEINFO_MEMBER(cls_name) = /
{ _T(#cls_name), TypeInfoOrder++, &(base_name::GetTypeInfoClass()), pfn_new };
#define IMPLEMENT_TYPEINFO_NULL(cls_name, pfn_new) /
TypeInfo cls_name::TYPEINFO_MEMBER(cls_name) = /
{ _T(#cls_name), TypeInfoOrder++, NULL, pfn_new }; /
bool cls_name::IsKindOf(TypeInfo& cls) /
{ /
TypeInfo* p = &(this->GetTypeInfo()); /
while( p != NULL ) /
{ /
if( p->type_id == cls.type_id ) /
return true; /
p = p->pBaseClass; /
} /
return false; /
}
// dynamically typeinfo
#define IMPLEMENT_DYNAMIC_CLS(cls_name, base_name) /
IMPLEMENT_TYPEINFO_CLS(cls_name, base_name, NULL)
#define IMPLEMENT_DYNAMIC_NULL(cls_name) /
IMPLEMENT_TYPEINFO_NULL(cls_name, NULL)
// dynamically constructable
#define IMPLEMENT_DYNCREATE_CLS(cls_name, base_name) /
IMPLEMENT_TYPEINFO_CLS(cls_name, base_name, cls_name::CreateObject) /
CBaseObj* cls_name::CreateObject(GCAlloc& gc) /
{ return /*new cls_name*/GC_NEW(gc, cls_name); } /
bool cls_name::m_bRegSuccess = /
REGISTER_TYPEINFO( _T(#cls_name), &(cls_name::TYPEINFO_MEMBER(cls_name)) );
#define IMPLEMENT_DYNCREATE_NULL(cls_name) /
IMPLEMENT_TYPEINFO_NULL(cls_name, cls_name::CreateObject) /
CBaseObj* cls_name::CreateObject(GCAlloc& gc) /
{ return /*new cls_name*/GC_NEW(gc, cls_name); } /
bool cls_name::m_bRegSuccess = /
REGISTER_TYPEINFO( _T(#cls_name), &(cls_name::TYPEINFO_MEMBER(cls_name)) );
//////////////////////////////////////////////////////////////////
// 动态指针转换宏定义
#define DYNAMIC_CAST(cls_name, object_ptr) /
dynamic_cast_t<cls_name>( TYPEINFO_OF_CLS(cls_name), object_ptr )
// 动态对象创建宏定义
#define DYNAMIC_CREATE(cls_name, key, gc) /
dynamic_create_t<cls_name>( key, gc )
//////////////////////////////////////////////////////////////////
// RTTI 起始类
class CBaseObj
{
DECLARE_DYNCREATE_NULL(CBaseObj)
};
//////////////////////////////////////////////////////////////////
// 动态指针转换函数模板
template <class T>
inline T* dynamic_cast_t(TypeInfo& cls, CBaseObj* ptr)
{
if( ptr )
return ptr->IsKindOf(cls) ? (T*)ptr : NULL;
else
return NULL;
}
// 动态对象创建函数
template <class T>
inline T* dynamic_create_t(LPCTSTR c_key, GCAlloc& gc)
{
if( c_key == NULL ) return NULL;
TypeInfo* inf = GET_TYPEINFO(c_key);
if( inf )
return DYNAMIC_CAST( T, inf->CreateObject(gc) );
else
return NULL;
}
//////////////////////////////////////////////////////////////////
#endif // __STDCPX_RTTI_H__
RTTI.cpp:
[cpp] view
plaincopy
#include "stdafx.h"
#ifndef __STDCPX_RTTI_H__
#include "detail//RTTI.h"
#endif
//////////////////////////////////////////////////////////////////
// type_id 自增量初始化
extern int TypeInfoOrder = 0;
// CBaseObj 成员定义
IMPLEMENT_DYNCREATE_NULL(CBaseObj)
在"struct TypeInfo"中我用到了许式伟的StdExt库,若要单独使用的话需要把"Map"改为"map",即使用stl的map完成同样的功能,并删除掉带有"GCAlloc"的语句.
此RTTI在使用上类似MFC的RTTI,所有需要用到RTTI功能的类必须继承自"class CBaseObj".
使用示例:
Show.h:
[cpp] view
plaincopy
class CShow : public CBaseObj
{
DECLARE_DYNAMIC_CLS(CShow, CBaseObj)
public:
CShow() {}
virtual ~CShow() {}
};
Show.cpp:
[cpp] view
plaincopy
IMPLEMENT_DYNAMIC_CLS(CShow, CBaseObj)
相关文章推荐
- 一个简单的C++的RTTI实现
- 一个简单的RTTI实现
- 一个简单的RTTI实现
- 一个简单的C++的RTTI实现
- 一个简单的RTTI实现
- 一个简单的Thread缓冲池的实现
- 利用xmlHttp实现一个简单的Ajax无刷新
- 一个简单的32位多任务操作系统的实现
- 一个简单聊天室的两种实现 (fcntl 和 select)
- 一个简单的Thread缓冲池的实现
- 分形介绍 && 一个简单的Kotch curve实现代码
- 一个简单的windows位图文件类的实现
- 一个单继承类体系的RTTI实现(根据类名判断类指针)
- 一个简单的用户登录接口asp实现
- 一个简单留言本的实现
- 如何实现一个简单的remoteing实例
- 遇到一个很难说话的人,要求在网页上点一下文字,变成另外一些文字,下面是简单的实现
- 一个简单的自定义ClassLoader的实现
- 一个在程序中实现plugin机制的简单例子
- J2ME应用实例——一个简单的计算器实现(附源代码)