/*********************************************************************************************************************
*   发布日期: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;
}

转载于:https://www.cnblogs.com/tinaluo/p/7826678.html

《深入浅出MFC》系列之动态创建相关推荐

  1. MFC中的动态创建与运行时识别

    MFC中支持运行时类型识别与动态创建.这更多的是设计问题.理解了其中的设计,可以更快定位用MFC框架开发的代码.通过研究MFC实现这些的细节,可以更快地掌握其他开发框架的设计思想. 宏定义中的&quo ...

  2. MFC关键技术-动态创建

    //a.h头文件 #pragma once #include"m.h" #include<iostream> using namespace std;class CSh ...

  3. 深入浅出mfc学习笔记——六大关键技术之仿真_运行时和动态创建

    1:PS88:MFC的类层次结构 <1>CObject <2>CCmdTarget,CDocument <3>CCmdTarget_CWinThread_CWinA ...

  4. MFC小程序003------MFC使用WebBrowser组件,在对话框中创建滚动视图,动态创建一个静态文本控件并设置鼠标单击的消息响应...

    MFC小程序截图: 一.在MFC中简单使用WebBrowser的ActiveX插件的方法: 见博文:  http://blog.csdn.net/supermanking/article/detail ...

  5. MFC动态创建控件并响应事件代码实现过程

    MFC动态创建控件以及响应动态创建的控件的事件的实现方法如下. 1.创建对象     用new进行动态创建一个对象.然后调用Create函数创建窗口,在函数的父窗口参数中传入this或者用AfxGet ...

  6. MFC中动态创建控件以及事件响应实现方法

    本文实例讲述了MFC中动态创建控件以及事件响应实现方法,分享给大家供大家参考.具体实现方法如下: 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态 ...

  7. MFC六大核心机制之三:动态创建

    MFC中很多地方都使用了动态创建技术.动态创建就是在程序运行时创建指定类的对象.例如MFC的单文档程序中,文档模板类的对象就动态创建了框架窗口对象.文档对象和视图对象.动态创建技术对于希望了解MFC底 ...

  8. MFC中动态创建控件以及添加事件响应

    本文实例讲述了MFC中动态创建控件以及事件响应实现方法,分享给大家供大家参考.具体实现方法如下: 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态 ...

  9. MFC中动态创建button及添加响应事件

    MFC中动态创建button及添加响应的事件,主要步骤如下:  1.在头文件(**Dlg.h)中添加一个CButton类型,  例如:CButton btn;  2.在(**Dlg.cpp)的OnIn ...

最新文章

  1. python4delphi_python4delphi 安装
  2. QString和string互相转换乱码处理
  3. python loop call soon_python3-asyncio 学习笔记 1 -- call_soon
  4. Windows Containers 大冒险: 加速
  5. Django Cookie于Session
  6. html:(36):间距和对齐
  7. C++学习之路 | PTA乙级—— 1073 多选题常见计分法 (20 分)(精简)
  8. oracle sql last_value,図でイメージするOracle DatabaseのSQL全集 第3回 分析関数
  9. 微信小程序学习笔记-1-环境及基础结构
  10. 8分钟搞清波士顿动力进化史 | 视频
  11. centOS7忘记密码重置方法
  12. 针对ASP.NET页面实时进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)...
  13. 阿里云云计算 8 ECS的实例规格
  14. 【转】RIS/PACS系统实施过程中Worklist的配置与调试
  15. java架构师一般多少岁,大量教程
  16. 如何从硬盘安装Linux
  17. Zemax学习笔记(7)- 双透镜设计实例
  18. 服务器固件降级需要重装系统吗,bios降级,小编教你bios可以降级吗
  19. 手机熊猫直播怎么投屏
  20. PDP激活被拒绝原因码表

热门文章

  1. 不错的jquery插件
  2. Linux 小知识翻译 - 「cron」
  3. Eclipse将android 类编译为jar类库
  4. DB2定时清理归档日志脚本
  5. SharePoint 2007 文件夹或者文件名过长
  6. FTP服务器如何实现安全性
  7. WPF线性渐变画刷应用之——炫彩线条
  8. [小技巧] gcc attribute error 属性小试
  9. Android教你打造独一无二的刷新加载框架
  10. 遍历替换字符串中特定字符