IsKindOf()函数

主要检查一下对象否从某一类类派生,但此类必须从CObject派生(或间接),并且使用DECLARE_DYNAMIC/DECLARE_SEARIAL等宏

比如我们函数的参数是个基类的指针类型。那么当我外部传过来一个子类的指针时,在函数内部就可以用这种语句来确认传进来的是这个子类的对象,而不是其它子类的对象

ASSERT(xxx->IsKinfOf(RUNTIME_CLASS(yyy)))
   判断xxx所指的类是否为yyy的子类!

指针的类型和指针指向的对象的类型可以是不一样的,这就是指针的灵活性;但是这种灵活性是不安全的,因为可以随意转换,所以前面用一个ASSERT判断一下。

其实现在在C++中也可以使用安全的类型转换:static_cast、dynamic_cast等。

======================================================================

知道有IsKindOf这么个函数,用来检测:(1)对象是否属于指定的类,(2)对象是否属于指定类派生的类,但是一直没用过,今天用了下,提示错误error C2039: ‘classXXX‘ : is not a member of ‘XXX‘,查了很多资料,才把它搞明白,记录如下:

1、对使用IsKindOf这个函数的类要在.h文件夹里定义DECLARE_DYNAMIC或DECLARE_SERIAL宏

class CDlgTest : public CDialog

{

DECLARE_DYNAMIC( CDlgTest )

// Construction

public:

CDlgTest(CWnd* pParent = NULL);   // standard constructor

...

...

};

2、需要在.cpp文件中加入IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL宏

[cpp] view plaincopy

IMPLEMENT_DYNAMIC(CDlgTest, CDialog)

CDlgTest::CDlgTest(CWnd* pParent )

: CDialog(CDlgTest::IDD, pParent)

{

...

}

3、使用时,CDlgTest dlg;

if(dlg.IsKinfOf(CDialog))...

随后又研究了一下这几个宏,也算明白了IsKindOf的实现原理,做下简单记录:

1、DECLARE_DYNAMIC宏

[cpp] view plaincopy

#define DECLARE_DYNAMIC(class_name)/

public:/

static CRuntimeClass class##class_name;/

virtual CRuntimeClass* GetRuntimeClass() const;

2、IMPLEMENT_DYNAMIC宏

[cpp] view plaincopy

#define IMPLEMENT_DYNAMIC(class_name,bass_class_name)/

_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)

#define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)/

static char _lpsz##class_name[]= #class_name;/

CRuntimeClass class_name::class##class_name = {/

_lpsz##class_name,sizeof(class_name),wSchema,pfnNew,/

RUNTIME_CLASS(base_class_name),NULL};/

static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);/

CRuntimeClass* class_name::GetRuntimeClass() const/

{ return &class_name::class##class_name;}

3、IsKindOf函数的实现

// example for CObject::GetRuntimeClass

CAge a(21);

CRuntimeClass* prt = a.GetRuntimeClass();

ASSERT( strcmp( prt->m_lpszClassName, "CAge" )  == 0 );

Return Value:

A pointer to the CRuntimeClass structure corresponding to this object‘s class; never NULL.

[cpp] view plaincopy

BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass *pClass) const

{

CRuntimeClass* pClassThis=this;

while(pClassThis != NULL)

{

if(pClassThis==pClass)

return TRUE;

pClassThis=pClassThis->m_pBaseClass;

}

return FALSE;

}

BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const

{

ASSERT(this != NULL);

// it better be in valid memory, at least for CObject size

ASSERT(AfxIsValidAddress(this, sizeof(CObject)));

// simple SI case

CRuntimeClass* pClassThis = GetRuntimeClass();

return pClassThis->IsDerivedFrom(pClass);

}

4、单行宏的定义

定义单行宏:主要有以下三种用法.

1) 前加##或后加##,将标记作为一个合法的标识符的一部分.注意,不是字符串.多用于多行的宏定义中.例如:

#define A(x)  T_##x

则 int A(1) = 10; //等效于int T_1 = 10;

#define A(x)  Tx##__

则 int A(1) = 10; //等效于int T1__ = 10;

2) 前加#@,将标记转换为相应的字符,注意:仅对单一标记转换有效

#define B(x) #@x

则B(a)即 ‘a‘,B(1)即 ‘1‘.但B(abc)却不甚有效.

3) 前加#,将标记转换为字符串.

#define C(x) #x

则C(1+1) 即 "1+1".

IsKindOf()函数

时间: 2024-10-31 13:19:22

IsKindOf()函数的相关文章

quick-cocos2d-x 学习系列之十四 测试用例

quick-cocos2d-x 学习系列之十四 测试用例 定义变量,创建13个场景名字 local items = { "framework.helper", "framework.native", "framework.display", "framework.crypto", "framework.network", "framework.luabinding", "fra

MFC DAY03 04 05

一 MFC的消息映射机制(3) 1 消息映射机制的使用 1.1 自己的类必须派生自 CCmdTarget 1.2 自己的类内 必须添加声明宏 DECLARE_MESSAGE_MAP 1.3 自己的类外 必须添加实现宏 BEGIN_MESSAGE_MAP( theClass, baseClass ) END_MESSAGE_MAP( ) 2 消息映射机制的实现 2.1 数据结构 struct AFX_MSGMAP_ENTRY (静态数组的每个元素) { UINT nMessage; // 消息ID

MFC 六大机制 (2) RTTI(运行时类型识别)

RTTI(Runtime Type Identification,运行时类型识别) 程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型.MFC 早在编译器支持 RTTI 之前,就具有了这项能力.承接上一章,我们现在要在 Console 程序中将 RTTI 仿真出来.我希望我的类库具备 IsKindOf() 的能力,能够在执行器检查某个对象是否"属于某种类",并传回 TRUE 或 FALSE.为了更直观地查看结果,我在 IsKindOf() 中加入了输出,使其达到如

学习VC MFC开发必须了解的常用宏和指令

1.#include指令  包含指定的文件 2.#define指令   预定义,通常用它来定义常量(包括无参量与带参量),以及用来实现那些"表面似和善.背后一长串"的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了 3.#typedef指令 常用来定义一个标识符及关键字的别名它是语言编译过程的一部分,但它并不实际分配内存空间. 4.#ifndef   #else   #endif指令  条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容

MFC框架

第一点:类别型录网的搭建: 类别型录网搭建的目的是为了实现所谓的"执行期类型识别",也就是在程序运行的时候识别出某个对象是否是某个类的实例(基类也可以).这里还不是很明白为什么需要实现"执行期类型识别",这种技巧具体被应用在哪里. 例如在MFC中CView继承于CWnd,那么可以进行这样的判断: CView view; bool result = view.IsKindOf(CWnd); // result == true 如上,通过调用IsKindOf函数,可以判

MFC总结

一MFC 的概念和作用 1 什么是MFC? 全称Microsoft Foundation Class Library 我们称之为 微软基础类库,封装了绝大部分WIN32 api 函数,还封装 了程序流程. 1.1 硬盘存在形式就是一个库(静态库/动态库) 1.2 原理上还是一个程序框架 2 为什么使用MFC? 基于框架编程,提供工作效率,减少开发周期,节约开发 成本. 二几个重要头文件 afx.h - MFC 绝大部分类的声明 afxwin.h - 包含了afx.h 和windows.h afx

MFC 六大机制

一.入口函数机制(程序启动机制) 语言总结: 3.1 构造theApp 对象CWinApp::CWinApp() 1)将&theApp 保存到当前程序模块状态信息中 2)将&theApp 保存到当前程序线程状态信息中 3)AfxGetApp/AfxGetThread - 返回&theApp 3.2 程序流程(WinMain) 1)利用AfxGetApp/AfxGetThread 获取&theApp 2)利用&theApp 调用应用程序类成员虚函数 InitAppli

学习VC MFC开发必须了解的常用宏和指令(转)————复习一下

1.#include指令  包含指定的文件 2.#define指令   预定义,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善.背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了 3.#typedef指令 常用来定义一个标识符及关键字的别名它是语言编译过程的一部分,但它并不实际分配内存空间. 4.#ifndef   #else   #endif指令  条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一

MFC六大核心机制之二:运行时类型识别(RTTI)

上一节讲的是MFC六大核心机制之一:MFC程序的初始化,本节继续讲解MFC六大核心机制之二:运行时类型识别(RTTI). typeid运算子 运行时类型识别(RTTI)即是程序执行过程中知道某个对象属于某个类,我们平时用C++编程接触的RTTI一般是编译器的RTTI,即是在新版本的VC++编译器里面选用“使能RTTI”,然后载入typeinfo.h文件,就可以使用一个叫typeid()的运算子,它的地位与在C++编程中的sizeof()运算子类似的地方(包含一个头文件,然后就有一个熟悉好用的函数