/*********************************************************************************************************************
* 发布日期:2017-11-13 16:23:44
* 进度:
* 作者:LuoTian
* 备注:动态创建
*********************************************************************************************************************/
这一篇承接上一篇的运行时类型识别,当各个类像链表一样串接之后,做各种功能就比较简单。
动态创建的思路:
动态创建就是指输入一个类名就能创建一个对象,比如在控制台中输入Base,就能创建Base类的对象。
假设有三个类Base,B,C,继承关系为Base<-B<-C,其中Base为根类。根据上一篇所写,将这三个类通过CRuntimeClass进行串接。因为动态创建需要这个,原因容易理解,假如你输入一个Base,程序则必须根据输入的这个字符串在链接的类中查找是否存在Base这个类,于是就需要遍历,从C开始一直查找到Base。
为了实现这些功能,除了在CRuntimeClass里面再添加一些信息之外,还在能动态创建的类中添加一个静态函数CreateObject( );
流程如下:
假定输入Base,程序根据pFirst从尾端开始遍历各个类,查找是否有类名=Base的类,如果不存在则程序返回。如果存在,再看它的一个字段m_pfnCreateObject是否为空,而这个m_pfnCreateObject是一个函数指针,所指向的就是在能动态创建的类中添加的静态函数CreateObject(),假如一个类不能动态创建,那么肯定没有这个CreateObject函数,则在初始化CRuntimeClass的时候,m_pfnCreateObject也就为NULL了,如果能动态创建,m_pfnCreateObject就指向了CreateObject( ),然后通过m_pfnCreateObject指针执行函数调用。
思路总结:
一、能动态创建的类中有CreateObject()函数。
二、能动态创建的类的CRuntimeClass结构中的m_pfnCreateObject字段初赋值为CreateObjec,如果为NULL,则不具备动态创建的能力。
//实现比较简单,直接new一个对象返回; static Base * PASCAL CreateObject(){return new B;}
示例代码如下:
#include <iostream> using namespace std; #define PASCAL _stdcall class Base; /***************核心的CRuntimeClass结构********************/ struct CRuntimeClass { char * name; //类名 int ClassSize; //类大小; Base *(PASCAL * m_pfnCreateObject)(); CRuntimeClass *pBase;//基类的CRuntimeClass地址 Base * CreateObject(); static CRuntimeClass * PASCAL Load(); static CRuntimeClass *pFirst; CRuntimeClass *pNext; }; CRuntimeClass * CRuntimeClass::pFirst=NULL;//pFirst初始化为空; CRuntimeClass* PASCAL CRuntimeClass::Load() { char szClassName[64]; CRuntimeClass* pClass; cout << "输入需要动态创建的类名:"; cin >> szClassName; //在各个类的CRuntimeClass结构中查找是否存在输入的类名 for (pClass = pFirst; pClass != NULL; pClass = pClass->pNext) { if (strcmp(szClassName, pClass->name) == 0) return pClass; } cout<<"没有找到该类名,程序退出!!"<<endl; return NULL; } Base * CRuntimeClass::CreateObject() { if (m_pfnCreateObject == NULL) { cout<<"不能动态创建!!"<<endl; return NULL; } else { Base * pObject =(*m_pfnCreateObject)(); return pObject; } } //****************结束*****************************************/ struct AFX_CLASSINIT { AFX_CLASSINIT(CRuntimeClass *pNewClass) { pNewClass->pNext=CRuntimeClass::pFirst; CRuntimeClass::pFirst=pNewClass; } }; class Base //根基类; { public: static CRuntimeClass classBase; virtual CRuntimeClass * GetRuntimeClass()const { return &Base::classBase; } virtual void SayHello() { cout<<"基类Base的SayHello"<<endl; } }; class B:public Base //B类 { public: static CRuntimeClass classB; static Base * PASCAL CreateObject(){return new B;} virtual CRuntimeClass * GetRuntimeClass()const{ return &B::classB; } virtual void SayHello(){ cout<<"类B的SayHello,动态创建对象成功!!"<<endl;} }; class C:public B //C类 { public: static CRuntimeClass classC; virtual CRuntimeClass * GetRuntimeClass()const{ return &C::classC; } }; //***********************实现部分*************************// struct CRuntimeClass Base::classBase={"Base",sizeof(Base),NULL,NULL}; static AFX_CLASSINIT _init_A(&Base::classBase);//② struct CRuntimeClass B::classB={"B",sizeof(B),B::CreateObject,&Base::classBase,}; static AFX_CLASSINIT _init_B(&B::classB);//③ struct CRuntimeClass C::classC={"C",sizeof(C),NULL,&B::classB,}; static AFX_CLASSINIT _init_C(&C::classC);//④ int main(int argc,char *argv[]) { CRuntimeClass * pClassRef; Base *pOb; cout<<"共有三个类Base,B,C,其中B类具有动态创建能力... ."<<endl; while(true) { if((pClassRef=CRuntimeClass::Load())==NULL) break; pOb=pClassRef->CreateObject(); if(pOb!=NULL) pOb->SayHello(); } return 0; }