最近开始学习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;