MFC抽象类之动态实现技术
来源:互联网 发布:浪人网络上机密码 编辑:程序博客网 时间:2024/05/18 02:04
MFC抽象类之动态实现技术
前不久,我在北大和哈工大bbs上问了同 一个问题"抽象类能实例化么 not sure",几天后得到大虾的解答,我自己又深入探讨了一些,写下这篇文章以让和我有同样问题的人能从苦恼中解脱出来.
众所周知,含有纯虚函数或者构造函数被声明为protected的类被称之为抽象类
,初学者在教科书上一定得到以下结论:"切记:抽象类不允许实例化".但在实际中
有例外.
//in XX.h
class OBJ
{
protected: OBJ();
//something else
friend OBJ*Createobj();//用static也行,mfc就用的是static
};
//in XX.cpp
OBJ::OBJ()
{cout<<"a obj is being created"<<endl;
}
OBJ*Createobj()
{return new OBJ();}
//in test.cpp
void main()
{
OBJ*ptr=Createobj();
delete ptr;
}
run后结果如下:
a obj is being created
Press any key to continue
看来是实例成功了,当然这个例子离动态创建还有区别,下面让我们看一看MFC是如何来进行动态创建的(不知你是否发现,在MFC的SDI和MDI程序中,都是用了动态创建机制,只是他使用了一些宏和CRuntimeClass这各类帮忙)
侯捷的"深入浅出MFC"中又很详细的关于这方面的讲解,不过他没有提到微软实现这种做法的目的之一是抽象类实例化的实现.
其实现过程大致如下:MFC利用一些宏DECLARE_DYNCREATE,IMPLEMENT_DYNCREATE将一些主要的东西悄悄的插入到将具有动态生成的类中,我们以SDI的CMainFrame的动态生成为例,看一看CMainFrame的声明文件,他的constuctor可是protected的呦,DECLARE_DYNCREATE在MainFrm.h中加了几个重要的函数,其中对动态创建至关重要的是
static CObject*PASCAL CreateObject();//他可是用来调用CMainFrame
static const AFX_DATA CRuntimeClass classCMainFrame; 的constuctor
看看他的实现:
CObject*PASCAL CreateObject()
{ return new CMainFrame;}
但是我们在源代码中好像看不到谁调用了这个函数,事实上微软很秘密的 把他转移给了CRuntimeClass结构
看看CRuntimeClass结构
struct CRuntimeClass
{
// Attributes
//somethingelse
CObject* (PASCAL* m_pfnCreateObject)();
//.....
// Operations
CObject* CreateObject();
//...........
};
这里我仅列出两个与动态创建有关的成员.
IMPLEMENT_DYNCREATE宏完成了CMainFrame类中CRuntimeClass classCMainFrame的初始化工作,看下面代码
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) /
CObject* PASCAL class_name::CreateObject() /
{ return new class_name; } /
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, /
class_name::CreateObject)
m_pfnCreateObject被赋值为CMainFrame::CreateObject,看出点门道了吧^_^.
再看看CObject* CRuntimeClass::CreateObject()的实现吧.
CObject* CRuntimeClass::CreateObject()
{
.........
return (*m_pfnCreateObject)();
}
也许你还是很糊涂,但不知道你了不了解SDI程序的启动过程,它启动时默认打开一个单文档文件,其调用顺序如下:
CWinapp::OnFileNew()--->CSingleDocTemplate::OpenDocumentFile()-->...CDocTemplate::CreateNewFrame()
而CDocTemplate::CreateNewFrame()的实现如下:
CDocTemplate::CreateNewFrame()
{//......
CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
//....
}
其中m_pFrameClass是指向CMainFrame成员CRuntimeClass classCMainFrame的指针,
下面从后到前捋清一下思路:
m_pFrameClass->CreateObject()返回(*m_pfnCreateObject)(),而后者指向的是static CMainFrame::CObject*PASCAL CreateObject();
现在一切都很清晰了.
- MFC抽象类之动态实现技术
- 经典抽象数据类型之堆栈实现(动态数组)
- MFC运行时动态类实现
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(三)---MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- 抽象工厂之“反射”技术
- C#多态实现之抽象类
- 设计模式学习(十四)————抽象工厂模式(使用Qt框架的反射技术——根据字符串动态创建类来实现)
- Servlet技术之GenericServlet抽象类(学习笔记)
- 8--黑马程序员---技术总结之抽象类、内部类
- Servlet技术浅析(一)之GenericServlet抽象类
- Servlet技术浅析(二)之HttpServlet抽象类
- MFC之系统托盘实现
- 网络游戏外挂制作之我所见(7)
- 外挂传奇(编者序)
- 外挂传奇----内存之旅(上篇)
- 中国高校勤工助学网站程序开发质量和管理标准化
- JavaServer Faces 技术使Web应用程序开发变得更容易
- MFC抽象类之动态实现技术
- 一个microsoft的.exe程序文件的启动过程
- Windows2000启动时加载的系统支持进程
- Visual C++.net与Visual C++6.0使用之差别
- MFC技术内幕系列之(一)---MFC应用程序“生死因果”内幕
- MFC技术内幕系列之(二)---MFC文档视图结构内幕
- MFC技术内幕系列之(三)----MFC执行期类型识别与动态创建技术内幕
- MFC技术内幕系列之(四)---MFC消息映射与消息传递内幕
- MFC技术内幕系列之(五)---MFC文档序列化内幕