高手请指教在多文档的程序中, InitInstance()这个关键的初始化函数中有这样一段代码************************************************************CMultiDocTemplate* pDocTemplate;
 pDocTemplate = new CMultiDocTemplate(
  IDR_PAINTETYPE,
  RUNTIME_CLASS(CPainterUsePatternDoc),
  RUNTIME_CLASS(CChildFrame), // custom MDI child frame
  RUNTIME_CLASS(CPainterUsePatternView));
 AddDocTemplate(pDocTemplate);*************************************************************里面的RUNTIME_CLASS没有见过,是什么东东?在AFX.H里面有源代码*************************************************************#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))#define ASSERT_KINDOF(class_name, object) \
 ASSERT((object)->IsKindOf(RUNTIME_CLASS(class_name)))*************************************************************这个定义我又有不明白,"##"是什么东东??在MSDN中查到*************************************************************#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;//将paster(n)定义为printf( "token" #n " = %d", token##n )//那么
paster( 9 );//这个函数等同于以下函数
printf( "token" "9" " = %d", token9 );
//就变成了printf( "token9 = %d", token9 );***********************************************************我们明白了'##'实际上就是连接两个字符串,回到刚才的定义#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))宏定义RUNTIME_CLASS(class_name)为((CRuntimeClass*)(&class_name::class##class_name))class_name是一个参数,代表了类名CRuntimeClass是一个结构RUNTIME_CLASS(CChildFrame) 等同于
((CRuntimeClass*)(&CChildFrame::classCChildFrame))
但这样定义了有什么用?

解决方案 »

  1.   

    RUNTIME_CLASS是一个宏,可以简单地理解它的作用:将类的名字转化为CRuntimeClass为指针。至于强制类型转换也是为了安全特性考虑的,因为从同一个基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要,但能避免一些可能出现的麻烦。
      

  2.   

    mfc中很多类都基于CObject,CObject中有一个获得类名称的虚函数class_name()。
    RUNTIME_CLASS宏就类似于这个函数的调用。
      

  3.   

    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* m_pBaseClass;
    // CRuntimeClass objects linked together in simple list
    static CRuntimeClass* pFirstClass; // start of class list
    CRuntimeClass* m_pNextClass; // linked list of registered classes
    };
    能具体说一下这个结构,是如何记录类的吗?
    在这里面m_lpszClassName是不是类名
      

  4.   

    这个结构是记录一连串的类的特征,m_lpszClassName就是一个保存在其中的类名
      

  5.   

    ((CRuntimeClass*)(&CChildFrame::classCChildFrame))
    前面是类型转换(CRuntimeClass*)
    后面不懂是什么?
    (&CChildFrame::classCChildFrame)
      

  6.   

    static CRuntimeClass* pFirstClass是这个链表的首,所以用静态类型,只有一个,
    m_pBaseClass记录当前类的基类的
    int m_nObjectSize表示类的空间大小
    CRuntimeClass* m_pNextClass表示连接在他下面的一个结构
      

  7.   

    这个于我们在代码里看到的DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏有关,classCChildFrame是由两部分class和CChildFrame连接起来的,后面的CChildFrame作为一个参数在动态创建和动态实现宏的一个参数
      

  8.   

    DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏有关???
    怎么相关??分是身外之物
      

  9.   

    每个CRuntimeClass对象,简单的说,是一个链表接点。
      

  10.   

    几句话也说不清,我也怕是自己的理解错误,你可以看侯杰的<深入浅出MFC>,上面很详细的
      

  11.   

    &CChildFrame::classCChildFrame
    请高手说明
    CChildFrame是一个类 
    我想:
    上面是先执行
    CChildFrame::classCChildFrame
    这是类的变量还是函数,定义了吗?为什么要再取地址‘&’
    再线等,弄清立刻结贴,信誉保证
      

  12.   

    他的思想就是遍历链表。无论是动态创建,还是动态识别,都需要遍历链表。一定的基础结构能完成一定的应用,从他的成员就看出来了(msdn):
    struct CRuntimeClass
    {
    LPCSTR m_lpszClassName;
    int m_nObjectSize;
    UINT m_wSchema
    CObject* (PASCAL* m_pfnCreateObject)( );
    CRuntimeClass* (PASCAL* m_pfnGetBaseClass)( );
    CRuntimeClass* m_pBaseClass;
    CObject* CreateObject( );
    BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;
    };他的效率在某些应用中比较低。如果这样的话,尽量避免遍历的出现,可以用一些状态变量完成某些工作。总之要从设计上的应用和结构来考虑。
      

  13.   

    给你看DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC的宏定义
    # define DECLARE_DYNAMIC(class_name)\      斜杠表示连接作用
    public:
        static CRuntimeClass class##class_name;\  //这里就是class##CChildFrame的连接
        virtual CRuntimeClass *GetRuntimeClasss() const;//*号实现的宏类似的太长了
      

  14.   

    1,你的view类DECLARE_DYNCREATE中有。 2,取地址。
      

  15.   

    RUNTIME_CLASS(CChildFrame) 等同于
    ((CRuntimeClass*)(&CChildFrame::classCChildFrame))class_name 为CChildFrame类
    &CChildFrame::classCChildFrame
    我想是
    将CChildFrame类中的一个叫做classCChildFrame 的变量的地址取出将其类型转换为struct CRuntimeClass *类型问题classCChildFrame这个变量还没定义吧?就算有定义,怎么能把一个变量的地址
    转换成结构指针??
      

  16.   

    我说过DECLARE_DYNCREATE有嘛。#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew)  AFX_DATADEF CRuntimeClass class_name::class##class_name = {  #class_name, sizeof(class class_name), wSchema, pfnNew,  RUNTIME_CLASS(base_class_name), NULL };  CRuntimeClass* class_name::GetRuntimeClass() const  { return RUNTIME_CLASS(class_name); } 
    class##class_name 他也是个结构。
      

  17.   

    上面是实现。 
    这是申明。静态的: 
    static AFX_DATA CRuntimeClass class##class_name;
      

  18.   

    呵呵,楼主有空去看看《MFC深入浅出》吧,里面有详细对MFC内部的主架构分析。