[MFC] RTTI应用总结(一)

来源:互联网 发布:appserv怎么进入mysql 编辑:程序博客网 时间:2024/05/29 12:56

[MFC] RTTI应用总结(一)

  • MFC RTTI应用总结一
    • MFC 六大机制之RTTI动态创建类
      • 概念介绍
      • CObject类介绍
      • 来自msdn
        • Members
      • 示例

MFC 六大机制之RTTI——动态创建类

概念介绍

RTTI (Runtime Type Identification)

MFC CObject 为基类,通过动态生成类机制完成了一整套MFC类的派生

使用CRunTimeClass类来实现整个动态的创建过程。

本文在Visual Studio 2013 + Windows7 环境下进行 MFC 应用程序的举例

CObject类介绍

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

注意:CObject类不支持多继承。派生的类仅仅拥有一个CObject基类,并且CObject在等级体系中必须位于最左边。不过,它也允许在多继承分支的右边有其结构及非CObject派生类。

来自msdn:

Members:


  • Protected Constructors

    Name Description CObject::CObject Default constructor.

  • Public Methods

    Name Description CObject::AssertValid Validates this object’s integrity. CObject::Dump Produces a diagnostic dump of this object. CObject::GetRuntimeClass Returns the CRuntimeClass structure corresponding to this object’s class. CObject::IsKindOf Tests this object’s relationship to a given class. CObject::IsSerializable Tests to see whether this object can be serialized. CObject::Serialize Loads or stores an object from/to an archive.

  • Public Opreators

    Name Description CObject::operator delete Special delete operator. CObject::operator new Special new operator.

示例

  • 动态创建类

    动态创建 顾名思义—只有在使用时创建 , CObject中的提供了一个CRuntimeClass的类 , 和对应的宏。

    而在实际的编程中, 主要是通过宏DECLARE_DYNCREATE 以及 IMPLEMENT_DYNCREATE 来提供和支持动态类创建的方法。

    要想一下子明白动态类的原理比较困难,所以我们先从它的表象—实现的方法来看。

    为此,我们来创建一个基于对话框的简单Demo,再加入两个对话框类,以体现一个需要动态创建类的模型。

    这里写图片描述

    旧 : 每用一个Dialog都去申请它的对象,并逐个执行。
    这里写图片描述
    这里写图片描述

    void CDemoDlg::OnBnClickedButton1(){    CDialog1 dlg;    dlg.DoModal();}void CDemoDlg::OnBnClickedButton2(){    CDialog2 dlg;    dlg.DoModal();}

    实现了两个模式对话框类的创建和对话框生成,但当需要创建多个对话框时,这种方式远远无法达到我们想要的效果。

    新 : 想要哪一个对话框就申请和生成哪一个,比如下面的这种方式
    这里写图片描述

    这里写图片描述

    这里写图片描述

    void CDemoNewDlg::OnBnClickedButton1(){    CString strDlgNo;    //获取需要生成的窗口编号    m_ctlDlgNum.GetWindowText(strDlgNo);    long class_no = atoi(strDlgNo);    //创建类名与对应键值    map<int, string> ClassMap;    ClassMap.insert(make_pair(1, "CDialog1"));    ClassMap.insert(make_pair(2, "CDialog2"));      //加载动态运行类    map<string, CRuntimeClass*> RunClassMap;    RunClassMap.insert(make_pair("CDialog1", RUNTIME_CLASS(CDialog1)));    RunClassMap.insert(make_pair("CDialog2", RUNTIME_CLASS(CDialog2)));    string class_name = ClassMap[class_no];    //动态生成对应CObject类    CObject* pObj = RunClassMap[class_name]->CreateObject();    //检查是否创建成功    ASSERT(pObj->IsKindOf(RunClassMap[class_name]));    //生成对话框    CDialogEx* pDlg = (CDialogEx *)pObj;    pDlg->DoModal();    //清理和回收内存    RunClassMap.empty();    delete pObj;}

当其中的一些步骤被拆分开,并实现成外部的配置项,我们就得到了真正的动态创建的全过程。

  • 关于动态创建的类的回收

    //清理和回收内存RunClassMap.empty();delete pObj;

    为什么要在这里使用delete呢?

    因为:

    #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, NULL)

    IMPLEMENT_DYNCREATE这个宏被定义成了一个一串带有CreateObject()的函数,它的返回值是一个new出来的指向对象的指针,所以在后面要对接收这个指针的pObjdelete处理,否则,不释放该部分内存会导致内存泄漏哦.

LL的话:对于动态创建类的这部分知识,我只是粗浅地介绍了一下,欢迎补充和指导,文章中有什么问题和错误,请不吝指出,谢谢!

参考:说说MFC中CRuntimeClass和CObject之间的那点事

原创粉丝点击