Dynamic Creation-动态创建
(本文以“MFC中RTTI技术的实现原理”为基础进行说明)
1、需求
给定一个类的名字CName,能够动态地创建该类的对象
2、需求分析
2.1、提供创建CName实例的函数,将该函数的指针作为CName的类型信息进行存储;
2.2、创建CName实例的函数的指针能够在CName实例化前被使用;
2.3、使用创建CName实例的函数的指针创建CName的实例;
2.4、使用方法
l 动态创建CName的实例
CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CName)
CObject* pObject = pRuntimeClass->CreateObject();//CName必须有一个缺省构造函数
Assert( pObject->IsKindOf(RUNTIME_CLASS(CName));//用IsKindOf检测是否是CName类的实例
4、普通实现
4.1、CRuntimeClass
struct CRuntimeClass
{
LPCSTR m_lpszClassName; //类的名字
CRuntimeClass* m_pBaseClass; //父类类型信息
CObject* (PASCAL* m_pfnCreateObject)(); // 创建对象的函数的指针
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const
{
const CRuntimeClass* pClassThis = this;
while (pClassThis != NULL) //循环取父类的类型信息
{
if (pClassThis == pBaseClass) return TRUE;
pClassThis = pClassThis->m_pBaseClass;
}
return FALSE;
}
CObject* CreateObject() //利用函数指针m_pfnCreateObject创建对象
{
if (m_pfnCreateObject == NULL) { return NULL;}
CObject* pObject = (*m_pfnCreateObject)();
return pObject;
};
4.2、CName
class CName:: CObject
{
public:
//必须有缺省构造函数
CName();
//取得静态变量classCName的指针
virtual CRuntimeClass* GetRuntimeClass() const
{
return (CRuntimeClass*) (&CName::classCName);
};
static CObject* PASCALCreateObject()
{
return new CName;
}
public:
//静态变量,保存类型信息,父类类型对象指定为继承的类的静态类型对象
static const CRuntimeClass classCName =
{ "CName ", (CRuntimeClass*) (&CObject:: classCObject) , CName:: CreateObject };
};
5、通过宏来简化实现
5.1、宏的定义
l DECLARE_DYNAMIC
#define DECLARE_DYNAMIC(class_name) \
public: static const AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
l IMPLEMENT_DYNAMIC
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, NULL)
l IMPLEMENT_RUNTIMECLASS
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, pfnNew) \
AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { \
#class_name, RUNTIME_CLASS(base_class_name), pfnNew, }; \
CRuntimeClass* class_name::GetRuntimeClass() const { return RUNTIME_CLASS(class_name); } \
l DECLARE_DYNCREATE
#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \
static CObject* PASCAL CreateObject();
l IMPLEMENT_DYNCREATE
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject* PASCAL class_name::CreateObject() { return new class_name; } \ //必须有缺省构造函数
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, class_name::CreateObject)
5.2、简化后的实现
l CName
//头文件
class CName:: CObject
{
DECLARE_DYNCREATE (CName)
};
//源文件
IMPLEMENT_ DYNCREATE (CName, CObject)
6、总结
6.1、静态变量的使用;
6.2、宏的使用;
6.3、为弄清原理,对MFC的源代码进行了简化;
(http://www.fanqiang.com)