`
isiqi
  • 浏览: 16365573 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论
阅读更多

关于RTTI

正如侯杰所说,文档视图是MFC进化为应用程序框架的灵魂,不可否认,这是MFC最为精炒的设计,十多年前数据与表现分离的思想就被应用在这个框架之上。而在文档视图之下,支撑着它的是运行时类型信息(RTTI)

RTTI允许程序在运行时刻获得类乃至普通类型的信息,这是怎么做到的,其实原理很简单,就是事先将这些信息保存为某种数据结构,保存的工作或由编译器帮你做,或由程序自己完成。程序运行的时候通过某种途径取得这些信息,然后根据这些信息来做运行时判断。

Delphi是一种RTTI非常强的原生语言,通过TypeInfo函数取得类型信息的进入点,然后你就可以判断它是整型还是字符串,是类还是其他的什么东西。如果是类,你可以取得类名,Published段的成员和方法地址,甚至你可以动态设置属性的值。看看它的快速开发环境,以及组件机制,都离不开RTTI的支持。JavaC#就更强了,C#的反射机制允许查询一个类的所有字段,方法属性以及事件。RTTI反映了一种语言的动态性。

那么是否RTTI越强就越好呢,不同的应用领域结论会有所不同,RTTI越强表明你要额外存储的信息就越多,对于上层应用来说当然无关紧要,但对于一些底层的开发,空间效率都是必须仔细考虑的,RTTI反而成了一种负担。

C++几乎是一种全能的语言,它要面对的是各种各样的应用,因而在RTTI这个问题上就不得不慎重行事,因此C++的类型信息仅止于类型的判断,当然你可以扩展,但Bjarne建议尽量少用RTTI。事实上C++背负了太多历史包袱,对很多新特性的支持都是举步维艰的,比如垃圾回收,Bjarne说过:“垃圾回收将使C++不适合做许多底层的工作,而这却正是它的一个设计目标如果原来就把垃圾回收作为C++的一个有机组件部分,那么C++早就可能成为死胎了。

回到MFC,它并没有使用C++自带的类型信息,可能是那些类型信息根本不够用,也可能是MFC出来的太早(类型信息在1993年才成为C++的一部分)MFC自己设计了一套RTTI机制,并用几个宏来简化代码的编写。

MFCRTTI

MFC中保存类型信息的是一个叫CRuntimeClass的结构体,声明如下:

struct CRuntimeClass

{

//类名

LPCSTR m_lpszClassName;

//类实例大小

int m_nObjectSize;

//是否支持序列化的标志

UINT m_wSchema;

//创建类实例的函数指针

CObject* (PASCAL* m_pfnCreateObject)();

//指向基类的运行时结构

CRuntimeClass* m_pBaseClass;

//创建类实例

CObject* CreateObject();

//判断是否从某个类继承而来

BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

//序列化支持

void Store(CArchive& ar) const;

static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

//组成运行时结构链表

CRuntimeClass* m_pNextClass;

};

一个具备类型信息的类都必须生成这个运行时结构,并将它保存为自己的静态成员。这个结构提供了三个方面的支持:

1. 类的基本信息,比如类名,对象尺寸,继承关系等。

你可以轻易判断两个类实例是否属于同一个类,比较m_lpszClassName,或比较类的RuntimeClass成员指针。

你可以通过IsDerivedFrom判断两个类的继承关系,前提是这两个类都生成了相应的RuntimeClass

2. 动态创建支持,将类的一个静态成员函数保存进m_pBaseClass,而该函数必然要进行New的操作,比如:

CObject* CTest::CreateObject()

{

return new CText;

}

以后我们用pRuntimeClass->CreateObject()来动态创建对象。

3. 序列化支持,这个以后再说。

现在假设有一个CMyMainFrm类需要类型信息,它的声明可能是这样:

class CMyMainFrm : public CFrameWnd

{

public:

//声明一个针对这个类的运行时结构体

static const CRuntimeClass classCMyMainFrm;

//多态支持

virtual CRuntimeClass* GetRuntimeClass() const;

//动态创建支持

static CObject* PASCAL CreateObject();

public:

CMyMainFrm();

};

实现则是这样:

CObject* PASCAL CMyMainFrm::CreateObject()

{

return new CMyMainFrm;

}

const CRuntimeClass CMyMainFrm::classCMyMainFrm = {

"CMyMainFrm",

sizeof(class CMyMainFrm),

0xFFFF,

CMyMainFrm::CreateObject,

(CRuntimeClass*)(&CFrameWnd::classCFrameWnd),

NULL};

CRuntimeClass* CMyMainFrm::GetRuntimeClass() const

{

return (CRuntimeClass*)(&CMyMainFrm::classCMyMainFrm);

}

CMyMainFrm::CMyMainFrm()

{

}

编写这些代码之后,CMyMainFrm便具备了类型信息,以后通过GetRuntimeClass取得运行时结构就可以在运行时做一些事情了。

与消息映射一样, 每一个类都要写这一堆代码实在是麻烦,使用宏简化一下吧,于是有了DECLARE_DYNCREATE IMPLEMENT_DYNCREATE宏;有些类可能只需要基本的类型判断,而不需要动态创建,于是有了DECLARE_DYNAMICIMPLEMENT_DYNAMIC宏;有些类还需要序列化的能力,于是有了DECLARE_SERIALIMPLEMENT_SERIAL

其中SERIAL包括DYNCREATEDYNCREATE包括DYNAMIC,总结起来如下表所示:

说明

DECLARE_DYNAMI IMPLEMENT_DYNAMIC

基本类信息判断

DECLARE_DYNCREATE

IMPLEMENT_DYNCREATE

基本类信息判断

动态创建

DECLARE_SERIAL

IMPLEMENT_SERIAL

基本类信息判断

动态创建

序列化支持

DYNCREATE为例,CMyMainFrm的声明和实现变成下面这样子:

class CMyMainFrm : public CFrameWnd

{

DECLARE_DYNCREATE(CMyMainFrm)

public:

CMyMainFrm();

};

IMPLEMENT_DYNCREATE(CMyMainFrm, CFrameWnd)

CMyMainFrm::CMyMainFrm()

{

}

类型信息使MFC有了一定的动态性,但这种动态性是受到限制的,要达到快速开发的级别仍然很难。不过有它的辅助已经可以完成很多高级的设计工作,比如文档视图,而这将是后面的主题。

分享到:
评论

相关推荐

    MFC源代码 RTTI.02

    MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 ...

    MFC的RTTI和动态创建仿真

    本文将深入探讨MFC如何实现RTTI和动态创建,并提供相关的实践应用。 首先,RTTI是C++的一个特性,允许程序在运行时获取对象的实际类型信息。在MFC中,RTTI主要通过`_tclass`宏和`dynamic_cast`关键字来实现。`_t...

    MFC RTTI代码(博客中使用资源)

    在这个MFC RTTI的代码示例中,我们将会探讨如何在MFC中实现和利用RTTI。 `DECLARE_DYNAMIC` 和 `IMPLEMENT_DYNAMIC` 是MFC中用于RTTI的关键宏,它们使得类能够支持`IsKindOf`和`DynamicCast`等运行时类型检查功能。...

    MFC的RTTI技术及动态创建的实现 详细介绍

    ### MFC的RTTI技术及动态创建的实现详解 #### 引言 MFC(Microsoft Foundation Classes)作为基于Windows API之上构建的C++类库,为开发者提供了强大的封装能力,简化了复杂的Windows编程细节,使其能够快速开发出...

    深入浅出MFC--教你看懂MFC的骨头

    并在其间深入介绍Runtime Type Information(RTTI)、Dynamic Creation、Persistence(Serialization)、Message Mapping、Command Routing等核心技术。这些技术正式其他书籍最缺乏的部分。此篇最后数章则脱离Scribble...

    MFC运行时类型识别(MFC RTTI)与动态创建.doc

    在MFC(Microsoft Foundation Classes)框架中,RTTI被用来增强面向对象编程的能力,特别是对于多态性和动态创建对象的支持。本文将详细探讨MFC中的RTTI实现以及它如何与动态创建相关联。 首先,为了利用MFC的RTTI...

    MFC-Class-Lib.rar_类库 lib 基类

    1. **CObject类**:所有MFC类的基类,提供了虚函数支持、运行时类型信息(RTTI)以及调试支持。 2. **CWinApp类**:代表一个应用程序实例,负责初始化、运行和结束应用程序。每个MFC应用程序都从CWinApp派生。 3. ...

    深入浅出MFC--教你看懂MFC的骨头.part5.rar

    并在其间深入介绍Runtime Type Information(RTTI)、Dynamic Creation、Persistence(Serialization)、Message Mapping、Command Routing等核心技术。这些技术正式其他书籍最缺乏的部分。此篇最后数章则脱离Scribble...

    深入浅出MFC--教你看懂MFC的骨头.part3.rar

    并在其间深入介绍Runtime Type Information(RTTI)、Dynamic Creation、Persistence(Serialization)、Message Mapping、Command Routing等核心技术。这些技术正式其他书籍最缺乏的部分。此篇最后数章则脱离Scribble...

    深入浅出MFC--教你看懂MFC的骨头.part4.rar

    并在其间深入介绍Runtime Type Information(RTTI)、Dynamic Creation、Persistence(Serialization)、Message Mapping、Command Routing等核心技术。这些技术正式其他书籍最缺乏的部分。此篇最后数章则脱离Scribble...

    深入浅出MFC--教你看懂MFC的骨头.part2.rar

    并在其间深入介绍Runtime Type Information(RTTI)、Dynamic Creation、Persistence(Serialization)、Message Mapping、Command Routing等核心技术。这些技术正式其他书籍最缺乏的部分。此篇最后数章则脱离Scribble...

    MFC中的RTTI,动态创建,消息机制

    在Microsoft Foundation Classes (MFC)库中,RTTI(运行时类型信息,Runtime Type Information)是一种强大的特性,它允许程序在运行时检查对象的类型。RTTI是C++标准库的一部分,但在MFC中得到了特别的增强,使得...

    RTTI.02.rar_visual c

    《深入理解MFC的RTTI:Visual C++实践解析》 在C++编程中,运行时类型信息(Run-Time Type Information,简称RTTI)是一种强大的工具,它允许程序员在程序运行时获取对象的类型信息。在MFC(Microsoft Foundation ...

    MFC基本运行原理简介

    在MFC中,通过重载`IsKindOf()`函数来实现RTTI功能,从而可以在运行时判断一个对象是否属于某个类或继承自某个基类。 2. **动态创建**: - 动态创建是指在运行时动态创建对象的过程。MFC通过`CObject`类及其派生类...

    MFC深入浅出 页面经剪裁,大小适中

    - RTTI(运行时类型识别):解释了RTTI的工作原理及其在MFC中的应用。 - 异常处理机制:介绍了C++异常处理机制的特点及如何在MFC中进行异常处理。 - 动态创建对象:探讨了动态创建对象的方法及其在MFC中的实现...

    MFC类库详解-中文版

    最顶层的CObject类是所有MFC类的基类,它提供了一些基本功能如动态类型信息、运行时类型信息(RTTI)、对象串行化和调试支持等。而CCmdTarget类封装了消息映射和命令传递相关的功能,实现了命令目标的概念。开发者...

    RTTI.rar_rtti

    在MFC(Microsoft Foundation Classes)框架中,RTTI同样被广泛应用于高级编程实践。 RTTI主要通过三个关键字来实现:`dynamic_cast`、`typeid`和`__typeof__`(在早期的Microsoft Visual C++中使用)。这些关键字...

    Visual C++权威剖析--MFC的原理、机制与开发实例

    动态类型信息(RTTI) MFC还提供了一种动态类型信息机制,允许在运行时获取对象的类型信息。这主要是通过`CRuntimeClass`类实现的,每个MFC类都会有一个与之关联的`CRuntimeClass`对象,包含了该类的名称、父类...

Global site tag (gtag.js) - Google Analytics