对MFC的动态创建的讨论!

anglely168 2002-08-14 05:41:53
CRuntimetimeClass结构里有成员
CObject* CreateObject();
CObject* (PASCAL* m_pfnCreateObject)();
而宏IMPLEMENT_DYNCREATE(CMyView, CView)总在类被事例化之前被调用,应次我们是不是可以下结论:在应用程中,只要申明了这个宏的类,内存中就保存了这个类的一个事例(通过CRuntimeClass中的m_pfnCreateObject指向这个事例)?
...全文
40 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
anni 2002-09-09
  • 打赏
  • 举报
回复
《深入浅出MFC》中有的,我这也有源码,给我留个言,我发给你
In355Hz 2002-08-16
  • 打赏
  • 举报
回复
简单点说就是static CObject* PASCAL CreateObject();不是申明变量,它申明的是一个函数。

这个函数的实现在IMPLEMENT_DYNCREATE的扩展中,如上文。

这个函数的指针保存在类的静态CRuntimeClass域的CObject* (PASCAL* m_pfnCreateObject)();成员变量,如上所示,它是一个定义与 CObject* PASCAL CreateObject();相同的函数指针。

然后RuntimeClass机制通过这个指针来由CRuntimeClass对象动态创建类的示例。
In355Hz 2002-08-16
  • 打赏
  • 举报
回复
m_pfnCreateObject是IMPLEMENT_DYNCREATE宏赋值的。比如对于CMyView,该宏是这样扩展的:

先扩展CMyView的static CObject* CreateObject函数的函数体:
CObject* PASCAL CMyView::CreateObject()
{ return new CMyView; } // 该函数的功能就是简单的创建CMyView对象。

然后经这个宏:
_IMPLEMENT_RUNTIMECLASS(CMyView, CView, wSchema,
CMyView::CreateObject)
//pfnNew参数为CMyView::CreateObject,就是刚才定义的函数。

扩展为用初始化块对类的static const CRuntimeClass classCMyView;成员赋初值(参考struct CRuntimeClass定义):

const CRuntimeClass CMyView::classCMyView = {
"CMyView", // 对应LPCSTR m_lpszClassName
sizeof(class CMyView), // 对应int m_nObjectSize
wSchema, // 对应UINT m_wSchema
CMyView::CreateObject, // 对应 CObject* (PASCAL* m_pfnCreateObject)();是个(CObject* (PASCAL*)())类型的函数指针。
RUNTIME_CLASS(CView), // 对应 m_pBaseClass,注意这个对DLL和非DLL的实现不同。
NULL }; // 对应 CRuntimeClass* m_pNextClass

最后实现CMyView从CObject继承的virtual CRuntimeClass* GetRuntimeClass() const 函数:

CRuntimeClass* CMyView::GetRuntimeClass() const
{ return RUNTIME_CLASS(CMyView); }

BTW:IMPLEMENT_DYNCREATE中间并不包含创建新对象的实际过程,它只是定义了创建新对象的方法而已。在没有调用CreateObject前,内存里实际没有任何a Instiance of CMyView。
anglely168 2002-08-14
  • 打赏
  • 举报
回复
to punpuny() :
thanks a lot!
IMPLEMENT_DYNCREATE什么时候执行?是在CMyView被运行前运行的,那应该是在内存全局区里保留了一个CRuntimeClass结构的区域,他的函数指针m_pfnCreateObject指向 a Instiance of CMyView,是吗?
punpuny 2002-08-14
  • 打赏
  • 举报
回复
不好意思,漏了一条。当定义DECLARE_DYNCREATE的时候,它还会加上
static CObject* PASCAL CreateObject();

所以CreateObject是CObject的一个静态成员变量。

至于_GetBaseClass的定义你可以看一下IMPLEMENT_RUNTIMECLASS这个宏,它是这样写的:
CRuntimeClass* PASCAL class_name::_GetBaseClass()
{return RUNTIME_CLASS(base_class_name);}

而RUNTIME_CLASS宏又是这样定义的:
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
所以_GetBaseClass函数其实返回的是基类的runtime class,即classCView
punpuny 2002-08-14
  • 打赏
  • 举报
回复
让我们假定这类叫做CMyView,从CView继承。

首先,当这个类的头文件中如果加上了DECLARE_DYNCREATE,那么在这个类中就会加上
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
static const AFX_DATA CRuntimeClass classCMyView;
virtual CRuntimeClass* GetRuntimeClass() const;
这三样东西。

然后当执行IMPLEMENT_DYNCREATE的时候,它其实是new了CMyView的一个实例,然后将classCMyView用{"CMyView", sizeof(CMyView), 0xFFFF, CMyView::CreateObject, CMyView::_GetBaseClass}来进行填充,到时候需要用到RUNTIME_CLASS(CMyView)的时候就返回这个classCMyView就可以了。

具体的代码你可以看一下这几个宏的定义,应该就很清楚了。
anglely168 2002-08-14
  • 打赏
  • 举报
回复
to In355Hz(好象一条狗):
怎么知道m_pfnCreateObject是指向CreateObject()的阿?没见它是怎么给这个指针assignment的阿!我是被这个宏搞得有点糊涂了!呵呵,好像这也是一个关键的地方!
webber84 2002-08-14
  • 打赏
  • 举报
回复
"在应用程中,只要申明了这个宏的类,内存中就保存了这个类的一个事例"
这个类是指什么类,CRuntimeClass? CRuntimerClass是通过类定义中(如CView定义中)的DECLARE_DYNCREATE(CMyView, CView)宏来成为该类的一个成员变量的。IMPLEMENT_DYNCREATE(CMyView, CView)对CRuntimerClass的成员进行了定义。
In355Hz 2002-08-14
  • 打赏
  • 举报
回复
不对吧?m_pfnCreateObject是一个函数指针啊!它指向的就是宏DECLARE_DYNCREATE定义的静态类函数:
static CObject* PASCAL CreateObject();

IMPLEMENT_DYNCREATE的定义里由这个函数的实现:
CObject* PASCAL CXXObject::CreateObject() { return new CXXObject; }

动态创建对象的时候就从RuntimeClass结构的m_pfnCreateObject调用这个函数就返回new的CXXObject对象。
c_vector 2002-08-14
  • 打赏
  • 举报
回复
<<深入浅出mfc>>有讲到,跟类继承结构有关,注意那个链表
andy_lau 2002-08-14
  • 打赏
  • 举报
回复
恩,深入浅出mfc中坦得很清楚
anglely168 2002-08-14
  • 打赏
  • 举报
回复
我就是在看这本书,有了这个想法阿!不过书中对于这个问题着墨不多,特别是对SeriaLize也没有给出具体的仿真!
大家有兴趣也看看这个问题:
http://www.csdn.net/expert/topic/934/934059.xml?temp=.995495
那边100也奉上!
dycdyc123 2002-08-14
  • 打赏
  • 举报
回复
这个........

MFC深入前出可以看看那

哪上面讨论的很仔细

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧