1:PS88:MFC的类层次结构
<1>CObject
<2>CCmdTarget,CDocument
<3>CCmdTarget_CWinThread_CWinApp
CCmdTarget_CWnd_CView
CCmdTarget_CWnd_CFrameWnd
C++规定,全局对象的构建将比程序进入点更早。所以theApp的构造函数将更早与main。
2:RTTI(运行时类型识别)
编译时需选用/GR选项——包含typeinfo.h——使用新的typeid运算符,我希望我的类库具备iskindof的能力,能在执行期侦测某个对象时候属于某种类并传回 True或False。
要达到RTTI的能力。我们的类设计者一定要在类建构起来的时候。记录必要的信息。以建立型录,型录中的类信息。以链表的方式连接起来。方便一一比较。
以CRuntimeClass结构体描述之,其中至少需要类名称。链表的Next指针,以及链表的First指针。由于first 指针属于全局变量。所以它应该以static修饰。
struct CRuntimeClass
{
LPCSTR m_lpszClassName;
int m_nObjectsize
CRuntimeClass* m_pBaseClass;
Static CRuntimeClass* pFirstClass;
CRuntimeclass * m_pNextClass;
};
我希望每个类都能拥有这样一个CRuntimeClass成员变量。
为了能把CRuntimeClass对象赛到类之中,并声明一个可以抓到该对象地址的函数。我们定义Declare_dynamic宏。
出现在宏定义中的##说明将两个字符串串在一起。
为了各个CRunTimeClass对象的内容指定以及连接工作使用Implement_Dynamic宏来完成。
#define Implement_Dynamic(class name,base_class name)\_Implement_RuntimeClass(Class_name,base_class_name,0xffff,NULL)
//in .h
class Cview:public Cwnd
{
Declare_dynamic(CView)
}
//in implementation file
IMPlement_dynmaic(CView,Cwnd)
链表的头总是需要特别处理。所以我们的类根源CObject不能使用上面的宏。
Iskindof(类型识别)
为CObject加上一个iskindof 函数,于是此函数将被所有类继承它将把参数所指定的某个CRuntimeClass对象拿来与类别型录中的元素一一比较,比较成功(在型录中发现),就传回TRUE。否则传回False
3:Dynamic creation(动态创建)
如果我能够把类的大小记录在类别型录中。把建构函数(即将出现的CRuntimeClass::CreateObject)也记录在类别型录中。当程序在执行器获得一个类名称,它就可以在类别型录网中找出对应的元素,然后调用其建构函数,产生出对象。
类的对象记录在类别型录中。建构函数也记录在类别型录中。当程序在执行期间获得一个类名称,它就可以在类别型录网中找出对应的元素。然后调用其建构函数产生对象。
CRuntimeClass中多了CObject* CreateObject();
static CRuntimeClass *PASCAL load();
为了适应这新增的两个宏。添加新宏Declare_dyncreate和Implement_dyncreate,从宏的定义中我们可以看到有用动态创建能力的类库必然也拥有运行时类型识别能力,因为_dyncreate宏覆盖了_dynamic宏。
在.h中Declare_dyncreate(CFramewnd);在,cpp中implement_dyncreate(CWnd,CCmdTarget)
总结下:
当知道一个类名,去判断有没有这个类时,即进行类型识别,这时就是去找这个链表的过程。
当需要动态创建时,仅仅是在CRuntimeClasss结构体增加了根据类型new 类对象的函数,在定义类类型时,类中的CRuntimeClasss成员也进行了这个类对象的创建,并保存了对象指针。
下面是csdn中一个网友提供的解释。供为参考。
2、使用时先通过宏RUNTIME_CLASS得到类的RunTime信息,当获得一个类名时,先用类别型录网判别这个类是否是链表中有的类,若是,就使用CRuntimeClass的成员函数CreateObject创建一个该类的实例。
3、CObject* pObject = pRuntimeClass->CreateObject();//完成动态创建
CRuntimeClass *pClassRef;
CObject* pOb;
while(1)
{
if((pClassRef=CRuntimeClass::load())==NULL)
break;
pOb= pClassRef->CreateObject();
if(pob!=NULL)
pob->SayHello();
}
http://www.pcdog.com/edu/vc/2005/12/g057056.html
http://hi.baidu.com/282535629/blog/item/6e59aec2defc2a3de5dd3bd5.html
http://www.ieing.cn/html-31903-1.html
http://hi.baidu.com/1005301774/blog/item/bd61b19173b7f887a877a445.html