您现在的位置:中国下载站学院中心网络编程Visual C++教程Visual C++入门教程 → 文章列表

MFC教程(3)-- CObject类

作者:佚名  来源:不详  发布时间:2007-3-27 17:32:58   

减小字体 增大字体

 
 

  CObject是大多数MFC类的根类或基类。CObject类有很多有用的特性:对运行时类信息的支持,对动态创建的支持,对串行化的支持,对象诊断输出,等等。MFC从CObject派生出许多类,具备其中的一个或者多个特性。程序员也可以从CObject类派生出自己的类,利用CObject类的这些特性。

  本章将讨论MFC如何设计CObject类的这些特性。首先,考察CObject类的定义,分析其结构和方法(成员变量和成员函数)对CObject特性的支持。然后,讨论CObject特性及其实现机制。

  CObject的结构

  以下是CObject类的定义:

  class CObject

  {

  public:

  //与动态创建相关的函数

  virtual CRuntimeClass* GetRuntimeClass() const;

  析构函数

  virtual ~CObject(); // virtual destructors are necessary

  //与构造函数相关的内存分配函数,可以用于DEBUG下输出诊断信息

  void* PASCAL operator new(size_t nSize);

  void* PASCAL operator new(size_t, void* p);

  void PASCAL operator delete(void* p);

  #if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)

  void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);

  #endif

  //缺省情况下,复制构造函数和赋值构造函数是不可用的

  //如果程序员通过传值或者赋值来传递对象,将得到一个编译错误

  protected:

  //缺省构造函数

  CObject();

  private:

  //复制构造函数,私有

  CObject(const CObject& objectSrc); // no implementation

  //赋值构造函数,私有

  void operator=(const CObject& objectSrc); // no implementation

  // Attributes

  public:

  //与运行时类信息、串行化相关的函数

  BOOL IsSerializable() const;

  BOOL IsKindOf(const CRuntimeClass* pClass) const;

  // Overridables

  virtual void Serialize(CArchive& ar);

  // 诊断函数

  virtual void AssertValid() const;

  virtual void Dump(CDumpContext& dc) const;

  // Implementation

  public:

  //与动态创建对象相关的函数

  static const AFX_DATA CRuntimeClass classCObject;

  #ifdef _AFXDLL

  static CRuntimeClass* PASCAL _GetBaseClass();

  #endif

  };

  由上可以看出,CObject定义了一个CRuntimeClass类型的静态成员变量:

  CRuntimeClass classCObject

  还定义了几组函数:

  构造函数析构函数类,

  诊断函数,

  与运行时类信息相关的函数,

  与串行化相关的函数。

  其中,一个静态函数:_GetBaseClass;五个虚拟函数:析构函数、GetRuntimeClass、Serialize、AssertValid、Dump。这些虚拟函数,在CObject的派生类中应该有更具体的实现。必要的话,派生类实现它们时可能要求先调用基类的实现,例如Serialize和Dump就要求这样。

  静态成员变量classCObject和相关函数实现了对CObjet特性的支持。

  CObject类的特性

  下面,对三种特性分别描述,并说明程序员在派生类中支持这些特性的方法。

  对运行时类信息的支持

  该特性用于在运行时确定一个对象是否属于一特定类(是该类的实例),或者从一个特定类派生来的。CObject提供IsKindOf函数来实现这个功能。

  从CObject派生的类要具有这样的特性,需要:

  定义该类时,在类说明中使用DECLARE_DYNAMIC(CLASSNMAE)宏;

  在类的实现文件中使用IMPLEMENT_DYNAMIC(CLASSNAME,BASECLASS)宏。

  对动态创建的支持

  前面提到了动态创建的概念,就是运行时创建指定类的实例。在MFC中大量使用,如前所述框架窗口对象、视对象,还有文档对象都需要由文档模板类(CDocTemplate)对象来动态的创建。

  从CObject派生的类要具有动态创建的功能,需要:

  定义该类时,在类说明中使用DECLARE_DYNCREATE(CLASSNMAE)宏;

  定义一个不带参数的构造函数(默认构造函数);

  在类的实现文件中使用IMPLEMENT_DYNCREATE(CLASSNAME,BASECLASS)宏;

  使用时先通过宏RUNTIME_CLASS得到类的RunTime信息,然后使用CRuntimeClass的成员函数CreateObject创建一个该类的实例。

  例如:

  CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CNname)

  //CName必须有一个缺省构造函数

  CObject* pObject = pRuntimeClass->CreateObject();

  //用IsKindOf检测是否是CName类的实例

  Assert( pObject->IsKindOf(RUNTIME_CLASS(CName));

  对序列化的支持

  “序列化”就是把对象内容存入一个文件或从一个文件中读取对象内容的过程。从CObject派生的类要具有序列化的功能,需要:

  定义该类时,在类说明中使用DECLARE_SERIAL(CLASSNMAE)宏;

  定义一个不带参数的构造函数(默认构造函数);

  在类的实现文件中使用IMPLEMENT_SERIAL(CLASSNAME,BASECLASS)宏;

  覆盖Serialize成员函数。(如果直接调用Serialize函数进行序列化读写,可以省略前面三步。)

  对运行时类信息的支持、动态创建的支持、串行化的支持层(不包括直接调用Serailize实现序列化),这三种功能的层次依次升高。如果对后面的功能支持,必定对前面的功能支持。支持动态创建的话,必定支持运行时类信息;支持序列化,必定支持前面的两个功能,因为它们的声明和实现都是后者包含前者。

  综合示例:

  定义一个支持串行化的类CPerson:

  class CPerson : public CObject

  {

  public:

  DECLARE_SERIAL( CPerson )

  // 缺省构造函数

  CPerson(){}{};

  CString m_name;

  WORD m_number;

  void Serialize( CArchive& archive );

  // rest of class declaration

  };

  实现该类的成员函数Serialize,覆盖CObject的该函数:

  void CPerson::Serialize( CArchive& archive )

  {

  // 先调用基类函数的实现

  CObject::Serialize( archive );

  // now do the stuff for our specific class

  if( archive.IsStoring() )

  archive << m_name << m_number;

  else

  archive >> m_name >> m_number;

  }

  使用运行时类信息:

  CPerson a;

  ASSERT( a.IsKindOf( RUNTIME_CLASS( CPerson ) ) );

  ASSERT( a.IsKindOf( RUNTIME_CLASS( CObject ) ) );

  动态创建:

  CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CPerson)

  //Cperson有一个缺省构造函数

  CObject* pObject = pRuntimeClass->CreateObject();

  Assert( pObject->IsKindOf(RUNTIME_CLASS(CPerson));

  实现CObject特性的机制

  由上,清楚了CObject的结构,也清楚了从CObject派生新类时程序员使用CObject特性的方法。现在来考察这些方法如何利用CObjet的结构,CObject结构如何支持这些方法。

  首先,要揭示DECLARE_DYNAMIC等宏的内容,然后,分析这些宏的作用。

  DECLARE_DYNAMIC等宏的定义

  MFC提供了DECLARE_DYNAMIC、DECLARE_DYNCREATE、DECLARE_SERIAL声明宏的两种定义,分别用于静态链接到MFC DLL和动态链接到MFC DLL。对应的实现宏IMPLEMNET_XXXX也有两种定义,但是,这里实现宏就不列举了。

  MFC对这些宏的定义如下:

  #ifdef _AFXDLL //动态链接到MFC DLL

  #define DECLARE_DYNAMIC(class_name)

  protected:

  static CRuntimeClass* PASCAL _GetBaseClass();

  public:

  static const AFX_DATA CRuntimeClass class##class_name;

  virtual CRuntimeClass* GetRuntimeClass() const;

  #define _DECLARE_DYNAMIC(class_name)

  protected:

  static CRuntimeClass* PASCAL _GetBaseClass();

  public:

  static AFX_DATA CRuntimeClass class##class_name;

  virtual CRuntimeClass* GetRuntimeClass() const;

  #else

  #define DECLARE_DYNAMIC(class_name)

  public:

  static const AFX_DATA CRuntimeClass class##class_name;

  virtual CRuntimeClass* GetRuntimeClass() const;

  #define _DECLARE_DYNAMIC(class_name)

  public:

  static AFX_DATA CRuntimeClass class##class_name;

  virtual CRuntimeClass* GetRuntimeClass() const;

  #endif

  // not serializable, but dynamically constructable

  #define DECLARE_DYNCREATE(class_name)

  DECLARE_DYNAMIC(class_name)

  static CObject* PASCAL CreateObject();

  #define DECLARE_SERIAL(class_name)

  _DECLARE_DYNCREATE(class_name)

  friend CArchive& AFXAPI operator>>(CArchiv


在百度中搜索更多MFC教程(3)-- CObject类相关网页 转贴于:中国下载站

  • 上一篇文章:MFC教程(4)-- 消息映射的实现(1)
  • 下一篇文章:MFC教程(2)-- MFC和Win32
  • 阅读统计:[]
  • 中国下载站】【设为主页】【收藏本页】【打印本文】【回到顶部】【关闭此页

    相关文章
    文章评论(评论内容只代表网友观点,与本站立场无关!)

    用户名: 查看更多评论

    分 值:100分 85分 70分 55分 40分 25分 10分 0分

    内 容:

             (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码


    设为首页 - 关于我们 - 广告服务 - 网站地图 - 加入收藏 - 网站声明 - 网站帮助 - 友情链接

    • Copyright (C) 2006-2008 www.cndownz.com All Rights Reserved.
      中国下载站 版权所有. 粤ICP备05141802号. 对本站有任何建议、意见或投诉,请来信:cndownzcom@yahoo.com.cn.
      喜欢中国下载站(cndownz.com),请把中国下载站(cndownz.com)告诉你QQ上的5位好友,多谢支持!