mfc动态创建(dynamic create)实现原理
来源:互联网 发布:信捷plc编程电缆dvp 编辑:程序博客网 时间:2024/05/19 08:44
在用到MFC的文档视图构架你可能有个非常迷惑的地方.就是很多类不知道在哪里就被莫名其妙的实例化了.
以单文档视图为例.代码中你能看到的的实例化的地方就只有两个一个是CWinApp的一个全局变量的实例化,另一个就是
CSingleDocTemplate 实例化.它的构造函数如下
CSingleDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
然后接下来的事就你迷惑了,先是继承自SingleDocTemplate的类实例化了继承自CFrameWnd的类和继承自CDocument的类,然后呢继承自CFrameWnd的类又实例化了继承自CView的类.
你可能会想到背后早有写好的代码去实例化这些类了,但是最令你疑惑的是我自己定义继承自啥CView,CDocument等类的类时名字是自己随便取的啊,之前写好的代码竟然能有未卜先知的能力知道这类名? 不然不知道一个类的类名怎么去实例化它啊?
MFC自然没这么神奇的能力.所以毫无疑问的一点是你定义的新类类名信息肯定会传到某个地方,然后在那里实例化该类.背后的机制咋样的呢?
这就是所谓的动态生成(dynamic creation)机制了啊.该机制有用到前面讲的RTTI,在RTTI的基础上再扩充一些功能.
动态创建的一个简单例子
1.CRuntimeClass的定义
首先CRuntimeClass定义中除了RTTI信息,添加
struct CRuntimeClass{
CObject* ( *m_pfnCreateObject)(); //函数指针,指向的函数中会通过new实例化一个对象
CObject* CreateObject()
//其他信息省略掉了
}
其中函数CreateObject定义如下
CObject* CRuntimeClass::CreateObject(){
CObject* pObect = NULL;
pObject =(*m_pfnCreateObject)();
}
2.宏DECLARE_DYNCEATE
假如定义一个继承自CDocument的类CMyDoc.
我们瞧下CSingleDocTemplate* pTmp = new(.... RUNTIME_CLASS(CMyDoc) ....) //这里忽略其他参数.
CMyDoc是怎么被创建的呢? 先看CMyDoc定义中的宏
////////CMyDoc头文件//////
DECLARE_DYNCEATE(CMyDoc)
///////////////////////////////////////////////
相当于:
static CObject* CreateObject();
static CRuntimeClass classCMyDoc;
宏定义:
#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \
static CObject* CreateObject();
3.宏IMPLEMENT_DYNCREATE
///////////CMyDoc cpp文件/////////////////
IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
/////////////////////////////////////////////////
上面的宏除了前面的RTTI信息外,还有个
CObject* CMyDoc::CreateObject(){
return new CMyDoc;
}
CMyDoc::classCMyDoc.m_pfnCreateObject = CMyDoc::CreateObject;
宏定义:
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject* class_name::CreateObject() \
{ return new class_name; } \
//IMPLEMENT_RUNTIMECLASS(......)//为讨论方便这里省略掉了
4.创建对象
有了上面两个宏,然后CSingleDocTemplate的构造函数中有个参数RUNTIME_CLASS(CMyDoc),我们知道
#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
的以传的参数实际上是一个指向CMyView中的static CRuntimeClass classCMyDoc的指针.
于是可以这样调用函数创建对象
CObject* pDoc = RUNTIME_CLASS(CMyDoc)->CreateObject();//实际上就是调用
CObject* CMyDoc::CreateObject(){
return new CMyDoc;
}
总结:
你可能看到上面一堆乱七八糟的东东,就想着真他妈扯蛋啊,搞到最后不就是只需要一个类的名字,然后用该名字来实例化一个类嘛.有必要搞得这么麻烦嘛
该功能说起来简单,但实现起来还真没其他简单方法啊,除非C++语法做些更改,编译器添加些额外支持.我们知道函数中可以随便传个啥参数.
但实例化一个类比如CView* view = new CView; //一个类的名字是不能做为参数的啊.
比如void CreateObject(string className){
className* view = new className;
}
这样的函数绝对无法通过编译的.但我们上面讲到的貌似是这样实现的.因为那是宏,只是简单的文字替换,宏的替换那一步还没有轮到编译器去干活.宏替换完了才是编译器上场.
有了宏可以把类名当"参数"一样用可以说实现了一大半功能了.实际上你如果只是通过前面的两个宏整出一个静态函数static CObject* CreateObject();完全就可以了.但这样显然实现的不够优雅嘛,并且既然有个CRuntimeClass了就干脆把动态创建对象的函数带到该结构体中岂不更好啊(很多地方都用到CRuntimeClass,动态类型识别,动态创建,序列化).
- mfc动态创建(dynamic create)实现原理
- MFC中的动态创建(Dynamic Create)
- MFC动态创建(dynamic creation)实现原理
- 深入浅出 MFC Dynamic Creation 动态创建
- 深入浅出MFC:MFC 的 Dynamic Creation(动态创建)
- Dynamic Creation(动态创建)
- C++对象动态生成(Dynamic Create)的简单实现
- C++对象动态生成(Dynamic Create)的简单实现
- MFC学习笔记四——动态创建 Dynamic Creation
- MFC动态子类(dynamic subclassing)
- MFC:关键技术之Dynamic Creation(动态生成)
- MFC 动态创建机制 模拟实现
- 动态规划(dynamic programming)原理
- 动态数据窗创建原理及实现
- 动态赋值弱类型值对象--Dynamic Create Value Object
- C++对象动态生成(Dynamic Create)的完善版本
- MFC解密(3) 动态创建
- MFC关键技术模拟(5)------动态创建
- python模块系列之-re
- 本地和win服务器无法复制粘贴文档
- 周末大法好
- Android 7.0工程之预编译jack服务器
- POJ 1215 Gondwanaland Telecom 笔记
- mfc动态创建(dynamic create)实现原理
- 最大的算式
- spring-ldap学习(一)
- 成功人士
- python实现链表增删
- 朴素bayes实战
- 说说我做Java开发这一年
- maven自动发布tomcat
- 如何绘画状态机来描述业务变化