您的位置:首页 > 编程语言 > C语言/C++

c++模拟MFC中运行时类型识别(RTTI)(Run-Time Type Identification)

2010-05-31 21:36 591 查看
// CRuntimeClass.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream.h>
typedef long BOOL;
#define TRUE 1
#define FALSE 0

//运行时类型识别
struct CMyRuntimeClass
{
char m_ClassName[32];                 //支持类名
int  m_ClassSize;                     //类的sizeof
CMyRuntimeClass* pParentClassName;    //szName的父类 -->基类的父类为空(技巧)
};

//基类
struct CMyObject
{
/************************************************************************
/*MFC中支持运行时识别的类甚至在没有实例之前 就可以获得该类的的一些信息
/*如类名 对象大小  其父类等信息
/*而这些信息都与该类密切相关
/*
/*而通过这些信息最自然想到的便是C++中的静态数据成员 其与类相关 而不依赖于类
/*的对象
/*而在定义类的时候必须要对静态数据成员进行初始化 所以再程序入口(main Winmain)
/*之前必须对其初始化 由此可以在静态成员数据中存放一些关于类型的一些信息 及
/*动态创建函数的  需要的时候得到这个静态数据成员就可以了
---------------------------------------------------------------------------
/*MFC中这个对象"约定"命名为 class##className的形式 我们为了模拟 所以也采用
/*这种方法
/************************************************************************/
static CMyRuntimeClass classCMyObject;

//动态识别一个类型是否从另一个类型派生而来(虚方法)(IsDerivedFrom)
virtual BOOL isKindOf(CMyRuntimeClass* pRuntimeClass)
{
if (pRuntimeClass == NULL)
{
return FALSE;
}

CMyRuntimeClass* pCurRuntimeClass = GetRunTimeClass();
while (pCurRuntimeClass)
{
if (pCurRuntimeClass->m_ClassName == classCMyObject.m_ClassName)
{
return TRUE;
}
pCurRuntimeClass = pRuntimeClass->pParentClassName;
}
return FALSE;
}

//动态得到一个对象所属类型的类型名称(虚方法)
virtual CMyRuntimeClass* GetRunTimeClass()
{
return &classCMyObject;
}
};

//派生类
struct CMyCmdTarget:public CMyObject
{
static CMyRuntimeClass classCMyCmdTarget;
virtual BOOL isKindOf(CMyRuntimeClass* pRuntimeClass)
{
if (pRuntimeClass == NULL)
{
return FALSE;
}

CMyRuntimeClass* pCurRuntimeClass = GetRunTimeClass();
while (pCurRuntimeClass)
{
if (pCurRuntimeClass->m_ClassName == pRuntimeClass->m_ClassName)
{
return TRUE;
}
pCurRuntimeClass = classCMyCmdTarget.pParentClassName;
}
return FALSE;
}

virtual CMyRuntimeClass* GetRunTimeClass()
{
return &classCMyCmdTarget;
}
};

#define MYRUNTIME_CLASS(class_name) ((CMyRuntimeClass*)(&class_name::class##class_name))

CMyRuntimeClass CMyObject::classCMyObject = {"CMyObject",sizeof(CMyObject),NULL};
CMyRuntimeClass CMyCmdTarget::classCMyCmdTarget = {"CMyCmdTarget",sizeof(CMyCmdTarget),MYRUNTIME_CLASS(CMyObject)};

int main(int argc, char* argv[])
{
CMyObject MyObj;
CMyCmdTarget MyCmd;

CMyObject* pCmd = new CMyCmdTarget;

cout << MYRUNTIME_CLASS(CMyObject)->m_ClassName << '/t' << flush;
cout << MYRUNTIME_CLASS(CMyObject)->m_ClassSize << endl;

cout << MYRUNTIME_CLASS(CMyCmdTarget)->m_ClassName << '/t' << flush;
cout << MYRUNTIME_CLASS(CMyCmdTarget)->m_ClassSize << endl;

int nRet1 = MyCmd.isKindOf(MYRUNTIME_CLASS(CMyObject));
if (nRet1)
{
cout << "CMyCmdTarget 派生自  CMyObject类" << endl;
}

int nRet2 = MyCmd.isKindOf(MYRUNTIME_CLASS(CMyCmdTarget));
if (nRet1)
{
cout << "CMyCmdTarget 派生自  CMyCmdTarget类" << endl;
}

return 0;
}

void fun()
{
//   CCmdTaget CmdObj;
//
//  // CmdObj.PrintName();
//
//   cout << MYRUNTIMECLASS(CMyObject)->m_lpszClassName << '/t' << flush;
//   cout << MYRUNTIMECLASS(CMyObject)->m_nObjectSize << endl ;
//
//   cout << MYRUNTIMECLASS(CCmdTaget)->m_lpszClassName << '/t' << flush;
//   cout << MYRUNTIMECLASS(CCmdTaget)->m_nObjectSize << endl ;
//
//   CMyObject* pObj = new CMyObject;
//
//   //判断pObj指向的对象类型是否由CMyObject派生
//   bool bRet1 = pObj->IsKindOf(MYRUNTIMECLASS(CMyObject));
//
//   bool bRet2 = pObj->IsKindOf(MYRUNTIMECLASS(CCmdTaget));
//
//   if ( pObj )
//   {
//     delete pObj;
//     pObj = NULL;
//   }
// 	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: