《第3章 CObject派生类.ppt》由会员分享,可在线阅读,更多相关《第3章 CObject派生类.ppt(40页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第3章章CObject类及其特性类及其特性3.1CObject的的结构结构3.2CObject类的类的三个三个特性特性3.3实现实现CObject特性的机制特性的机制第第3章章CObject类类CObject是大多数是大多数MFC类的根类或基类。类的根类或基类。CObject类特性:类特性:运行时类信息运行时类信息动态创建动态创建串行化串行化对象诊断输出对象诊断输出?DumpConTextCObject派生类派生类:具备其中的一个或者多个特性。具备其中的一个或者多个特性。从从CObject类派生自己的类,利用类派生自己的类,利用CObject类特性。类特性。CObject类及其派生类类及其派
2、生类3.1CObject类的结构类的结构classCObjectprotected:CObject();/默认默认构造函数构造函数public:virtualCObject();/析构函数析构函数void*PASCALoperatornew(size_tnSize);/运算符运算符void*PASCALoperatornew(size_t,void*p);voidPASCALoperatordelete(void*p);#ifdefined(_DEBUG)&!defined(_AFX_NO_DEBUG_CRT)void*PASCALoperatornew(size_tnSize,LPCSTRl
3、pszFileName,intnLine);#endifprivate:CObject(constCObject&objectSrc);/复制构造复制构造函数函数,没有实现没有实现voidoperator=(constCObject&objectSrc);/赋值运算符赋值运算符Public:BOOLIsSerializable()const;/是否支持序列化是否支持序列化virtualvoidSerialize(CArchive&ar);/序列化函数序列化函数virtualvoidAssertValid()const;/断言机制断言机制virtualvoidDump(CDumpContext&
4、dc)const;/对象诊断输出对象诊断输出virtualCRuntimeClass*GetRuntimeClass()const;/;/运行时类信息运行时类信息staticconstAFX_DATACRuntimeClassclassCObject;/运行时类信息运行时类信息对象对象BOOLIsKindOf(constCRuntimeClass*pClass)const;/判断对象的类型判断对象的类型#ifdef_AFXDLLstaticCRuntimeClass*PASCAL_GetBaseClass();/获取基类获取基类#endif;CRuntimeClass:运行时类信息。运行时类信
5、息。CObject类的方法类的方法构造函数构造函数protected:CObject();/默认默认构造函数构造函数运算符运算符newdelete=公共方法公共方法BOOLIsSerializable()const;/是否支持序列化是否支持序列化BOOLIsKindOf(constCRuntimeClass*pClass)const;/判断对象的类型判断对象的类型可重载可重载virtualvoidSerialize(CArchive&ar);virtualvoidAssertValid()const;virtualvoidDump(CDumpContext&dc)const;virtualCR
6、untimeClass*GetRuntimeClass()const;静态方法静态方法staticconstAFX_DATACRuntimeClassclassCObject;/运行时类信息运行时类信息对象对象staticCRuntimeClass*PASCAL_GetBaseClass();/获取基类获取基类问题:如果有一个派生类那么它有问题:如果有一个派生类那么它有哪些方法?哪些方法?它将继承所有非静态方法它将继承所有非静态方法对于静态方法还需要自己添加对于静态方法还需要自己添加派生类自动具有这些方法派生类自动具有这些方法派生类不具有的方法派生类不具有的方法3.2CObject类的类的三个
7、三个特性特性1.支持运行时类信息支持运行时类信息的派生类的派生类2.支持动态创建支持动态创建的派生类的派生类3.支持支持序列化的序列化的派生类派生类3.2.1支持运行时类信息支持运行时类信息1,运行时类信息运行时类信息在运行时确定一个对象是否是在运行时确定一个对象是否是一个一个类类或其派或其派生类生类的实例的实例CObject提供提供IsKindOf函数实现这个功能函数实现这个功能2,如判断如判断m_Entity是否是是否是CLine的实例的实例.类类的程序表示:的程序表示:名名字:字:classname字字符符串:串:“classname”MFC对象:对象:CRuntimeClass类对象类
8、对象RUNTIME_CLASS(Cline)宏宏CRuntimeClass*pRuntimeClass=RUNTIME_CLASS(CLine);BOOL IsAObject=mEntity.IsKindOf(pRuntimeClass);3.2.1支持运行时类信息支持运行时类信息3支持支持运行时类信息运行时类信息的的CObject派生类派生类的设计方法的设计方法1.1.使用使用CObject或其派生类作为基类或其派生类作为基类2.2.在类说明中使用宏在类说明中使用宏DECLARE_DYNAMIC(CLASSNMAE););3.3.在类实现文件中使用宏在类实现文件中使用宏IMPLEMENT_D
9、YNAMIC(CLASSNAME,BASECLASS)。例如:设计如图所示的一组类例如:设计如图所示的一组类3.2.1支持运行时类信息支持运行时类信息4CEntity类的设计类的设计ClassCEntity:CObjectDECLARE_DYNAMIC(CEntity)Public:CEntity();CEntity();5CEntity类的实现类的实现IMPLEMENT_DYNAMIC(CEntity,CObject)CEntity:CEntity()CEntity:CEntity().3.2.1支持运行时类信息支持运行时类信息4CLine类的设计类的设计class CLine:CEntit
10、yDECLARE_DYNAMIC(CLine);private:intstartx,starty,endx,endy;public:CLine();CLine(intx1,inty1,intx2,inty2);4CLine类的类的实现实现IMPLEMENT_DYNAMIC(CLine,CEntity)CLine:CLine()CLine:CLine(intx1,inty1,intx2,inty2)startx=x1;starty=y1;endx=x2;endy=y2;CLine:CLine().3.2.1支持运行时类信息支持运行时类信息问题:问题:CEllipse、CText和和CRectan
11、gle如何实现如何实现运运行时类信息行时类信息的支持。的支持。3.2.1支持运行时类信息支持运行时类信息问题:问题:这两这两个个宏宏DECLARE_DYNAMIC(CLASSNMAE);IMPLEMENT_DYNAMIC(CLASSNAME,BASECLASS)为派生类至少添加了比为派生类至少添加了比CObject缺少的两个成员缺少的两个成员staticconstAFX_DATACRuntimeClassclassCLASSNMAE;staticCRuntimeClass*PASCAL_GetBaseClass();3.2.2支持动态创建支持动态创建设计设计支持动态创建支持动态创建的类的设计方
12、法的类的设计方法使用使用CObject类或其派生类作为基类类或其派生类作为基类定义类,用定义类,用DECLARE_DYNCREATE(CLASSNMAE)宏;宏;定义定义和实现和实现默认构造函数;默认构造函数;类实现类实现,用用IMPLEMENT_DYNCREATE(CLASSNAME,BASECLASS)宏宏使用动态创建使用动态创建CRuntimeClass*pRuntimeClass=RUNTIME_CLASS(CNname)CObject*pObject=pRuntimeClass-CreateObject();Assert(pObject-IsKindOf(RUNTIME_CLASS(
13、CName);3.2.3对序列化的支持对序列化的支持1序列化序列化把对象存入文件或从文件中读取对象内容的过程。把对象存入文件或从文件中读取对象内容的过程。2设计可序列化的类设计可序列化的类定义该类时,定义该类时,使用使用CObject类或其派生类作为类或其派生类作为基类基类使用使用DECLARE_SERIAL(CLASSNMAE)宏;宏;定义默认构造函数;定义默认构造函数;在类实现中使用在类实现中使用IMPLEMENT_SERIAL(CLASSNAME,BASECLASS)宏;宏;覆盖覆盖Serialize成员函数。成员函数。3.2.3对序列化的支持对序列化的支持3序列化序列化类的设计举例类的
14、设计举例可序列化的可序列化的CEntity类的设计类的设计ClassCEntity:CObjectDECLARE_SERIAL(CEntity)/Public:CEntity();/CEntity();virtualvoidSerialize(CArchivear);使用使用CObject类或其类或其派生类作为基类派生类作为基类使用使用DECLARE_SERIAL(CLASSNMAE)宏宏定义默认构造函数定义默认构造函数覆盖覆盖Serialize成员函成员函数数3.2.3对序列化的支持对序列化的支持可序列化的可序列化的CEntity类的实现类的实现IMPLEMENT_SERIAL(CEntit
15、y,CObject)CEntity:CEntity().voidCEntity:Serialize(CArchivear)CObject:Serialize(ar);.使用使用IMPLEMENT_SERIAL宏宏实现默认构造函数实现默认构造函数实现实现Serialize成员函数成员函数3.2.3对序列化的支持对序列化的支持3序列化序列化类的设计举例类的设计举例可序列化的可序列化的CLine类的设计类的设计ClassCLine:CObjectDECLARE_SERIAL(CLine)/Public:CLine();/CLine();virtualvoidSerialize(CArchivear)
16、;使用使用CObject类或其类或其派生类作为基类派生类作为基类使用使用DECLARE_SERIAL(CLASSNMAE)宏宏定义默认构造函数定义默认构造函数覆盖覆盖Serialize成员函成员函数数3.2.3对序列化的支持对序列化的支持可序列化的可序列化的CLine类的实现类的实现IMPLEMENT_SERIAL(CLine,CEntity)CLine:CLine().voidCLine:Serialize(CArchivear)CEntity:Serialize(ar);if(ar.IsStoring()arstartxstartyendxstartxstartyendxendy;使用使用
17、IMPLEMENT_SERIAL宏宏实现默认构造函数实现默认构造函数实现实现Serialize成员函数成员函数作业:作业:CEllipse、CText和和CRectangle如何实现对序列化如何实现对序列化的支持。的支持。串行化串行化DECLARE_SERIALIMPLEMENT_SERIAL动态创建动态创建DECLARE_DYNCREATEIMPLEMENT_DYNCREATE三种三种CObject特性的关系特性的关系运行时类信息运行时类信息DECLARE_DYNAMICIMPLEMENT_DYNAMIC3.3实现实现CObject特性的机制特性的机制运行时类信息(动态信息)运行时类信息(动
18、态信息)类定义:类定义:DECLARE_DYNAMIC(class_Name)类实现:类实现:IMPLEMENT_DYNAMIC(class_Name,baseClass_Name)动态创建动态创建类定义:类定义:DECLARE_DYNCREATE(class_Name)类实现:类实现:IMPLEMENT_DYNCREATE(class_Name,baseClass_Name)序列化序列化类定义:类定义:DECLARE_SERIAL(class_Name)类实现:类实现:IMPLEMENT_SERIAL(class_Name,baseClass_Name)DECLARE_DYNAMIC的定义的
19、定义#defineDECLARE_DYNAMIC(class_name)protected:staticCRuntimeClass*PASCAL_GetBaseClass();public:staticconstAFX_DATACRuntimeClassclass#class_name;virtualCRuntimeClass*GetRuntimeClass()const;:换行符:换行符#:连接符:连接符DECLARE_DYNAMIC的定义的定义#defineDECLARE_DYNCREATE(class_name)DECLARE_DYNAMIC(class_name)staticCObje
20、ct*PASCALCreateObject();#defineDECLARE_SERIAL(class_name)_DECLARE_DYNCREATE(class_name)friendCArchive&AFXAPIoperator(CArchive&ar,class_name*&pOb);DECLARE_DYNAMIC的定义的定义DECLARE_DYNAMIC(CEntity)宏的展开宏的展开protected:staticCRuntimeClass*PASCAL_GetBaseClass();public:staticconstAFX_DATACRuntimeClassclassCEnti
21、ty;virtualCRuntimeClass*GetRuntimeClass()const;DECLARE_DYNAMIC的定义的定义DECLARE_DYNCREATE(CEntity)宏展开宏展开protected:staticCRuntimeClass*PASCAL_GetBaseClass();public:staticconstAFX_DATACRuntimeClassclassCEntity;virtualCRuntimeClass*GetRuntimeClass()const;staticCObject*PASCALCreateObject();DECLARE_DYNAMIC的定
22、义的定义DECLARE_SERIAL(CEntity)宏的展开宏的展开protected:staticCRuntimeClass*PASCAL_GetBaseClass();public:staticconstAFX_DATACRuntimeClassclassCEntity;virtualCRuntimeClass*GetRuntimeClass()const;staticCObject*PASCALCreateObject();friendCArchive&AFXAPIoperator(CArchive&ar,class_name*&pOb);DECLARE_DYNAMIC的定义的定义4支
23、持动态创建的支持动态创建的CEntity类的设计类的设计ClassCEntity:CObjectDECLARE_DYNAMIC(CEntity)Public:CEntity();CEntity();ClassCEntity:CObjectprotected:staticCRuntimeClass*PASCAL_GetBaseClass();public:staticconstAFX_DATACRuntimeClassclassCEntity;virtualCRuntimeClass*GetRuntimeClass()const;Public:CEntity();CEntity();DECLAR
24、E_DYNCREATEClassCEntity:CObjectprotected:staticCRuntimeClass*PASCAL_GetBaseClass();public:staticconstAFX_DATACRuntimeClassclassCEntity;virtualCRuntimeClass*GetRuntimeClass()const;staticCObject*PASCALCreateObject();friendCArchive&AFXAPIoperator(CArchive&ar,CEntity*&pOb);Public:CEntity();CEntity();DEC
25、LARE_DYNCREATEDECLARE_SERIALDECLARE_DYNAMIC3.4CRuntimeClass类类StructCRuntimeClassLPCSTRm_lpszClassName;/类的名字类的名字intm_nObjectSize;/类的大小类的大小UINTm_wSchema;/类的版本号类的版本号CObject*(PASCAL*m_pfnCreateObject)();/函数指针函数指针CRuntimeClass*(PASCAL*m_pfnGetBaseClass)();/函数指针函数指针/基类的基类的CRuntimeClass对象指针对象指针CRumtieClass
26、*m_pBaseClass;CObject*CreateObject();BOOLIsDerivedFrom(constCRuntimeClass*pBaseClass)const;staticCRuntimeClass*PASCALFromName(LPCSTRlpszClassName);staticCRuntimeClass*PASCALFromName(LPCWSTRlpszClassName);CObject类与类与CRuntimeClass与与RUNTIMECLASS相关部分的类定义相关部分的类定义classCObject.Public:virtualCRuntimeClass*G
27、etRuntimeClass()const;staticconstAFX_DATACRuntimeClassclassCObject;BOOLIsKindOf(constCRuntimeClass*pClass)const;#ifdef_AFXDLLstaticCRuntimeClass*PASCAL_GetBaseClass();#endif.;CRuntimeClass对象的属性值对象的属性值classCEntity的初始化:的初始化:成员变量成员变量说明说明取值取值m_lpszClassName类的名字类的名字类名类名“CEntity”m_nObjectSize类的大小类的大小类大小:类
28、大小:sizeof(CEntity)m_wSchema类的版本号类的版本号0,1,2或或-1等等m_pfnCreateObject函数指针函数指针CreateObject函数地址函数地址m_pfnGetBaseClass函数指针函数指针GetBaseClass()函数地址函数地址m_pBaseClass基类的基类的CRuntimeClass对对象指针象指针基类的基类的CRuntimeClass对象指对象指针针CObject类与类与CRuntimeClass问题:当类具有多层继承的时候,类中有多少个问题:当类具有多层继承的时候,类中有多少个RuntimeClass对象呢?对象呢?CObject:
29、classCObjectCEntity:classCEntityCLine:classCLineCEllipse:classCElliseCText:classCTextCREctangle:classCREctangle成员函数成员函数CreateObject的实现的实现CObject*CRuntimeClass:CreateObject()if(m_pfnCreateObject=NULL)/判断函数指针是否空判断函数指针是否空TRACE(_T(“Error:Tryingtocreateobjectwhichisnot)_T(DECLARE_DYNCREATEnorDECLARE_SERI
30、AL:%hs.n),m_lpszClassName);returnNULL;/函数指针非空,继续处理函数指针非空,继续处理CObject*pObject=NULL;TRYpObject=(*m_pfnCreateObject)();/动态创建对象动态创建对象END_TRYreturnpObject;成员函数成员函数IsDerivedFrom的实现的实现BOOLCRuntimeClass:IsDerivedFrom(constCRuntimeClass*pBaseClass)constconstCRuntimeClass*pClassThis=this;while(pClassThis!=NUL
31、L)/从本类开始向上逐个基类搜索从本类开始向上逐个基类搜索if(pClassThis=pBaseClass)/若是参数指定的类信息若是参数指定的类信息returnTRUE;pClassThis=pClassThis-m_pBaseClass;returnFALSE;/搜索完毕,没有匹配,返回搜索完毕,没有匹配,返回FALSE。RUNTIME_CLASS宏宏RUNTIME_CLASS宏的定义宏的定义#defineRUNTIME_CLASS(class_name)/(&class_name:class#class_name)RUNTIME_CLASS(CSudent)宏的实现宏的实现(&CStud
32、ent:classCStudent)用途:已知类名的情况下,返回用途:已知类名的情况下,返回RuntimeClass对象。对象。CRuntimeClass*m_RuntimeClass=RUNTIME_CLASS(CLine);CObject*pObject=m_RuntimeClass-CreateObject();FromName函数函数FromName函数函数:staticCRuntimeClass*PASCALFromName(LPCSTRlpszClassName);作用:按作用:按字符串类名字符串类名返回该类返回该类CRuntimeClass对象对象应用举例:动态获取应用举例:动态
33、获取CRuntimeClass对象对象LPCSTRclassNameStr=“CLine”;CRuntimeClass*pRuntimeClass=CRuntimeClass:FromName(classNameStr);CObject*pObject=pRuntimeClass-CreateObject();3.3.4序列化类的其它实现机制序列化类的其它实现机制与序列化类相关的与序列化类相关的MFC类:归档类类:归档类Carchive:支持简单类型的数据和复杂对象的读写操作。支持简单类型的数据和复杂对象的读写操作。写操作符写操作符和读操作符和读操作符CreateObject()SERIAL:SerializeCarchive类及类及操作操作类的表示类的表示RUNTIMECLASS机制机制RUNTIMECLASS(ClassName)宏宏CRuntimeClass:FromName(“ClassName”)下一步下一步后面,将开始讲解我们的后面,将开始讲解我们的图形交互程序图形交互程序案例案例设计步骤:设计步骤:1实体类的设计实体类的设计2文档类的设计文档类的设计3视图类的设计视图类的设计4应用程序界面应用程序界面5上述四个步骤的迭代,直到程序设计结束。上述四个步骤的迭代,直到程序设计结束。问题:如何设计实体类、文档类和视图类?问题:如何设计实体类、文档类和视图类?