最近开始学习VC了,谈谈心得吧。班门弄斧,请多多指教。
心得之一:
MFC中RuntiemClass支持的实现:
只要是从CObject派生的类,可以轻松实现RuntiemClass支持。当然,是通过编译器提供的宏来实现的。那么其实现机制是怎样的呢?我觉得只需要四个步骤。
首先让我们简化一下CRuntiemClass和CObject的定义,抽取出与RuntiemClass相关的部分:
struct CRuntimeClass
{
char m_lpszClassName[255];
int m_nObjectSize;
CObject* (*m_pfnCreateObject)();
CObject* CreateObject();
};
class CObject
{
public:
virtual CRuntimeClass* GetRuntimeClass() const {return NULL;}
static CRuntimeClass classCObject;
virtual ~CObject(){};
protected:
CObject(){printf("CObject constructed\n");}
};
我所说的四个步骤是(下面的操作都是对于从CObject派生的类而言的):
1.添加CRuntiemClass类型的静态成员classCMyClass(请把CMyClass换成你的类名)
static CRuntimeClass classCMyClass;
2.覆盖父类(即CObject)的GetRuntimeClass()方法,使之返回classCMyClass的指针
3.添加并实现 CreateObject();方法。
声明: static CObject* CreateObject();
实现:CObject* CMyClass::CreateObject() { return new CMyClass; }
4.为classCMyClass赋值。使m_lpszClassName="CMyClass";
m_nObjectSize=sizeof (CMyClass);
函数指针m_pfnCreateObject指向CMyClass::CreateObject。
CRuntimeClass CMyClass::classCMyClass= {"CMyClass",sizeof (CMyClass),
CMyClass::CreateObject};
附上完整的例程(摘自Programming Visual C++6.0 Unleashed):
#include <stdio.h>
#define RUNTIME_CLASS(class_name) (&class_name::class##class_name)
class CObject;
struct CRuntimeClass
{
char m_lpszClassName[21];
int m_nObjectSize;
CObject* (*m_pfnCreateObject)();
CObject* CreateObject();
};
class CObject
{
public:
virtual CRuntimeClass* GetRuntimeClass() const {return NULL;}
static CRuntimeClass classCObject;
virtual ~CObject(){};
protected:
CObject(){printf("CObject constructed\n");}
};
CRuntimeClass CObject::classCObject=
{"CObject",sizeof(CObject),NULL};
CObject* CRuntimeClass::CreateObject()
{
return (*m_pfnCreateObject)();
}
class CAlpha:public CObject
{
public:
virtual CRuntimeClass* GetRuntimeClass() const
{
return &classCAlpha;
}
static CRuntimeClass classCAlpha;
static CObject* CreateObject();
protected:
CAlpha(){printf("CAlpha constructor\n");}
};
CRuntimeClass CAlpha::classCAlpha={"CAlpha",sizeof(CAlpha),CAlpha::CreateObject};
CObject* CAlpha::CreateObject()
{
return new CAlpha;
}
class CBeta:public CObject
{
public:
virtual CRuntimeClass* GetRuntimeClass() const {return &classCBeta;}
static CRuntimeClass classCBeta;
static CObject* CreateObject();
protected:
CBeta(){printf("CBeta constructed\n");}
};
CRuntimeClass CMyClass::classCMyClass= {"CMyClass",sizeof (CMyClass),
CMyClass::CreateObject};
CRuntimeClass CBeta::classCBeta={"CBeata",sizeof(CBeta),CBeta::CreateObject};
CObject* CBeta::CreateObject()
{
return new CBeta;
}
class CGama:public CObject
{
public:
virtual CRuntimeClass* GetRuntimeClass() const { return &classCGama;}
static CRuntimeClass classCGama;
static CObject* CreateObject();
protected:
CGama(){printf("CGama constructed\n");}
};
CRuntimeClass CGama::classCGama={"CGama",sizeof(CGama),CGama::CreateObject};
CObject* CGama::CreateObject()
{
return new CGama();
}
int main()
{
printf("Entering dynCreate main\n");
CRuntimeClass* pRTCAlpha=RUNTIME_CLASS(CAlpha);
CObject* pObj1=pRTCAlpha->CreateObject();
printf("class of pObj1=%s\n",pObj1->GetRuntimeClass()->m_lpszClassName);
CRuntimeClass* pRTCBeta=RUNTIME_CLASS(CBeta);
CObject* pObj2=pRTCBeta->CreateObject();
printf("class of pObj2=%s\n",pObj2->GetRuntimeClass()->m_lpszClassName);
CRuntimeClass* pRTCGama=RUNTIME_CLASS(CGama);
CObject* pObj3=pRTCGama->CreateObject();
printf("class of pObj3=%s\n",pObj3->GetRuntimeClass()->m_lpszClassName);
delete pObj1;
delete pObj2;
delete pObj3;
return 0;
}