IMPLEMENT_DYNCREATE 动态创建机制

动态创建机制

在CRuntimeClass结构中加入了两个元素
CObject* CreateObject()函数和static CRuntimeClass PASCAL Load()
于是又多了两个宏
DECLARE_DYNCREATE宏和IMPLEMENT_DYNCREATE宏
#define DECLARE_DYNCREATE(class_name)\
      DECLARE_DYNAMIC(class_name)\
      static Cobject* PASCAL CreateObject();


#define IMPLEMENT_DYNCREATE(class_name,base_class_name)\
      CObject* PASCAL class_name::CreateObject()\
      {returnnew class_name;}
      _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,\
      class_name::CreateObject)
由上可知,DECLARE_DYNCREATE是DECLARE_DYNAMIC的增强版,也就是说,拥有动态创建能力的类库,必然亦有运行时类型识别能力
class CFrameWnd:public CWnd
{
DECLARE_DYNCREAT(CFrameWnd)
};
IMPLEMENT_DYNCREATE(CFrameWnd,CWnd)

于是被展开如下
class CFrameWnd:public CWnd
{
public:
static CRuntimeClass classCFrameWnd;
virtual CRuntimeClass* GetRuntimeClass() const;
static CObject* PASCAL CreateObject();
}


CObject* PASCAL CFrameWnd::CreateObject()
{return new CFrameWnd;}
static char _lpszCFrameWnd[]="CFrameWnd";
CRuntimeClass CFrameWnd::classCFrameWnd={
_lpszCFrameWnd,sizeof(CFrameWnd),0xFFFF,CFrameWnd::CreateObject,RUNTIME_CLASS(CWnd),NULL};
staitc AFX_CLASSINIT _init_CFrameWnd(&CFrameWnd::classCFrameWnd);
CRuntimeCLass* CFrameWnd::GetRuntimeClass() const
    {return &CFrmaeWnd::classCFrameWnd;}
这个类所有的结构中的m_pfnCreateObject不再为NULL,而是被赋予函数指针CFrameWnd::CreateObject,而用DECLARE_DYNAMIC来声明时这个函数指针被赋值NULL,因为DECLARE_DYNAMIC不具有动态创建功能,所以这个创建函数指针为NULL
在main()函数中加上这一段代码
void main()
{
CRuntimeClass* pClassRef;
CObject* pOb;
while(1)
if((pClassRef=CRAuntimeClass::Load())==NULL)
break;//只有当CRAuntimeClass::Load()传回NULL时,while循环才会停止
pOb=pClassRef->createObject();
if(pOb!=NULL)
pOb->SayHello();
}

CObject* CRuntimeClass::CreateObject()
{
if(m_pfnCreateObject==NULL)
{
TRACE1("ERROR:Trying to create objcet which is not"
     "DECLARE_DYNCREATE nor DECLARE_SERIAL:%HS\n",m_lpszClassName);
return NULL;
CObject* pObject=NULL;
pObject=(*m_pfnCreateObject)();
return pObject;
}


CObject* pObject=NULL;
pObject= (*m_pfnCreateObject)();
return pObject;
}
这个函数先检查结构中的m_pfnCreateObject是否为空,为空则不能创建对象,凡是m_pfnCreateObject不为NULL者,即可动态创建,若不为空,则利用m_pfnCreateObject所指向的函数来创建一个对象的指针。
CRuntimeClass* PASCALCRuntimeClass::Load()
{
char szClassName[64];
CRuntimeCLass* pClass;
cout<<"enter a class name:"<<endl;
cin>>szClassName;
for(pClass=pFirstClass;pClass!=NULL;pClass=pClass->m_pNextClass)
{
if(strcmp(szClassName,pClass->m_lpszClassName)==0;
return pClass;
}
TRACE1("ERROR:class not found:%s \n",szClassName;
return NULl;
}
这个函数首先需要输入一个类名,CRuntimeCLass* pClass这条代码声明了一个结构的指针,然后利用这个指针来遍历链表
当找到和这个类名相同的类时,则返回这个类的结构的指针,即pClass。


这其中有几个creat函数,共有三个,其联系如下
在结构中有:
CObject* (PASCAL* m_pfnCreateObject)();称为函数一
CObject* CreateObject();函数二
在类中有static CObject* PASCAL CreateObject();函数三

基中,函数一是用来记录函数三的指针的,因为想要访问这个类时可以获得的只有这个类的结构指针而以
函数二则是通过调用函数一来实现创建对象的,并且在函数二中还要对m_pfnCreateObject进行检查是否为NULL

函数三在类定义中,如上面的
CObject* PASCAL CFrameWnd::CreateObject()
{return new CFrameWnd;}
返回的是一个当前类对象的指针

通过以上方式可以看到,要动态创建一个类对象,有如下几个步骤
1.类说明中使用DECLARE_DYNCREATE(CLASSNMAE)宏;和在类的实现文件中使用IMPLEMENT_DYNCREATE(CLASSNAME,BASECLASS)宏;这个宏完成构造CRuntimeClass对象,并加入到链表中。

2、使用时先通过宏RUNTIME_CLASS得到类的RunTime信息,当获得一个类名时,先用类别型录网判别这个类是否是链表中有的类,若是,就使用CRuntimeClass的成员函数CreateObject创建一个该类的实例。
3、CObject* pObject = pRuntimeClass->CreateObject();//完成动态创建

 

转自:http://blog.sina.com.cn/s/blog_53b6bdf80100nzll.html

你可能感兴趣的:(C++)