1、在《mfc vc6技术内幕》一书中第五页有这么一句话:
“当一个类支持mfc的运行期类型信息(rtti)时,它能相应对它的名字和它的基类的请求。”不知应该如何理解这句话?
2、同书第六页还有一句话:
“DynCreate类的一个扩展类是DynCreate类。当一个类是DynCreate时,只需知道运行期而不是编译时该类的名字,程序就能构造该类的对象。”请问我如何才能其运行期的名字呢?
“当一个类支持mfc的运行期类型信息(rtti)时,它能相应对它的名字和它的基类的请求。”不知应该如何理解这句话?
2、同书第六页还有一句话:
“DynCreate类的一个扩展类是DynCreate类。当一个类是DynCreate时,只需知道运行期而不是编译时该类的名字,程序就能构造该类的对象。”请问我如何才能其运行期的名字呢?
//CRuntimeClass大概是下面这个样子,我找不到源代码,下面的代码与实际有出入:
struct CRuntimeClass
{
//Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema;// schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)();//NULL =>abstract class
CRuntimeClass* ( PASCAL* m_pfn_GetBaseClass )( )
CRuntimeClass* m_pBaseClass; //CRuntimeClass objects linked together in simple list
static CRuntimeClass* pFirstClass; // start of class list
CRuntimeClass* m_pNextClass; //linked list of registered classes
};
//////////////////////
就是通过这样一个数据结构,组成了一个像链表一样的网,说它是链表,因为它有next指针,但它还含有一个指向基类数据结构的指针,这样就组成了一个网,该数据结构保存了每一个类的重要属性,其中就包括该类的默认构造函数的指针,当你定义了一个类,通过两个宏,可以把它加入到这个网中,当然以后要查找某个对象的信息,搜索这个表就可以了。将新类加入到这个网的就是我们常见到的宏
DECLARE_DYNIMIC(class_name)
IMPLEMENT_DYNIMIC(class_name, base_class_name)
或是由它衍生出来的
//支持动态创建对象:
DECLARE_DYNCREATE(class_name)
IMPLEMENT_DYNCREATE(class_name, base_class_name)
//支持永久保存:
DECLARE_SERIAL(class_name)
IMPLEMENT_SERIAL(class_name, base_class_name)如果想了解再多,还是看看《深入浅出MFC》吧。
难道你不觉得第一句是个病句吗,翻译者在这里纯粹是以其昏昏使人昭昭!不知道RTTI和动态生成的困难在哪里,谈何理解他的解决办法。
给你举个典型的需要动态生成的例子:////////////////
#include <iostream.h>class ancestor
{......};class father : public ancestor
{.......};class mother : public ancestor
{.......};class uncle : public ancestor
{.......};void main()
{
char classname[64];
cout<<"Please input the class name:"<<endl;
cin>>classname;
ancestor * newobject = new classname;
....
}
////////////////////“请问我如何才能其运行期的名字呢?”
对,我们在编译期是不会知道classname到底是ancestor或father或mather
这在运行时通过用户输入来确定
我们根据用户输入的类名来创建一个对象,那么程序最后一行行得通吗?
不行,new后面必须是确定的类型
这就是动态生成的困难!其实我们大可这样来解决这个问题:
///////////////////////
#include <iostream.h>class ancestor
{......};class father : public ancestor
{.......};class mother : public ancestor
{.......};class uncle : public ancestor
{.......};void main()
{
char classname[64];
cout<<"Please input the class name:"<<endl;
cin>>classname;
ancestor * Object;
switch (classname)
{
case "ancestor":
Object=new ancestor;
break;
case "father":
Object=new father;
break;
.........
}
}//////////////////可是这样有点苯,MFC有更好的办法(形式上更优美),《深入浅出MFC》说的比较清楚,可以看看。
这与动态创建有什么关系,还不如说C++的多态性?
真的没人可以解释一下吗
第二名可能指支持动态创建的派生类也支持动态创建吧,也不大明白。
如何得到其运行期类名例子:(cage从cobject派生),
CAge a(21);
CRuntimeClass* prt = a.GetRuntimeClass();
ASSERT( strcmp( prt->m_lpszClassName, "CAge" ) == 0 );
你可以解释或推荐其他参考资料吗?
楼主问:“我如何才能其运行期的名字呢?”
我说就可以在程序运行时由用户输入。
我认为这是一个没有多大实际意义却是最直观的一个例子