// 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; }