zoukankan      html  css  js  c++  java
  • RUNTIME_CLASS、DECLARE_DYNAMIC、DECLARE_DYNCREATE、DECLARE_SERIAL宏定义

    RUNTIME_CLASS、DECLARE_DYNAMIC、DECLARE_DYNCREATE、DECLARE_SERIAL宏定义

    RUNTIME_CLASS( class_name )

    【参数】

    class_name:类的实际名字(不用引号括起来)。

    【说明】

    利用这个宏通过C++类的名字获得一个运行时类结构。

    RUNTIME_CLASS为class_name指定的类返回一个指向CRuntimeClass结构的指针。只有用DECLARE_DYNAMIC,DECLARE_DYNCREATE或DECLARE_SERIAL定义的CObject的派生类才能返回CRuntimeClass结构指针。更多的信息参见“Visual C++程序员指南”中的“CObject类”主题。

    【示例】

    // RUNTIME_CLASS的例子

    CRuntimeClass* prt = RUNTIME_CLASS(CAge);
    
    ASSERT( lstrcmp( prt->m_lpszClassName, "CAge" ) == 0 );

    学MFC学到文档,视图和框架的时候,明白必需在这三个类的派生类的类声明里加上DECLARE_DYNCREATE,然后在类声明外合适的地方加上IMPLEMENT_DYNCREATE,然后文档,视图和框架,还有文档模板就能够协调务工了。查看MSDN,发现类似的宏有这几对:

    DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC

    DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE

    DECLARE_SERIAL 和 IMPLEMENT_SERIAL

     

    1. RUNTIME_CLASS宏定义

    #define RUNTIME_CLASS(class_name)
    ((CRuntimeClass*)(&class_name::class##class_name))

    其中##的意思是把##两边的符号都停止宏扩展(假如它们是宏的话),然后把扩展后的内容连接在一起,中间不加空格。例如:RUNTIME_CLASS(CView)将被扩展成:

    (CRuntimeClass*)(&CView::classCView)

    但那个classCView是什么意思?原来,classCView是由DECLARE_DYNAMIC(CView)引入的唯一public属性的CRuntimeClass类别的静态成员变量:

    static const AFX_DATA CRuntimeClass classCView;

    原来RUNTIME_CLASS的功能就引用由DECLARE_DYNAMIC宏引入的静态成员变量。

    2. DECLARE_DYNAMIC(class_name)
    由于篇幅理由,宏的具体定义代码Code就不列出来了,感兴趣的能够去看文档afx.h。

    该宏往类中声明了三个成员:

    protected:
    
    static CRuntimeClass* PASCAL _GetBaseClass();
    
    public:
    
    virtual CRuntimeClass* GetRuntimeClass() const;
    
    static const AFX_DATA CRuntimeClass class##class_name;

    有两个成员参数,唯一静态成员变量class+类名,同RUNTIME_CLASS相似,如果是DECLARE_DYNAMIC(CView)的话,那个静态成员变量将是classCView。可见这个成员变量的名字是和DECLARE_DYNAMIC的参数parameter有关的。在下文把那个成员变量统统记做class##class_name。

    那个静态成员和两个成员参数在哪里被初始化和具体呈现呢?原来是在IMPLEMENT_DYNAMIC宏里。

    3. IMPLEMENT_DYNAMIC(class_name, base_class_name)

    查看它的宏定义,假如_AFXDLL被定义了的话,由DECLARE_DYNAMIC引入的成员的初始化和呈现是那样的:

    CRuntimeClass* PASCAL class_name::_GetBaseClass()
    {
      return RUNTIME_CLASS(base_class_name);
    }
    
    CRuntimeClass* class_name::GetRuntimeClass() const
    {
      return RUNTIME_CLASS(class_name);
    }
    
    AFX_COMDAT const AFX_DATADEF
    
    CRuntimeClass class_name::class##class_name =
    {
    #class_name,
    sizeofclass class_name), 0xFFFF, NULL, NULL, &class_name::_GetBaseClass, NULL
    };

    //这是在初始化静态成员变量class##class_name。

    //CRuntimeClass框架的各个成员的意义可查看msdn。

    4. _DECLARE_DYNAMIC(class_name)

    该宏的定义和DECLARE_DYNAMIC(class_name)基本相同。不相同之处是静态成员class##class_name前面没有const修饰符。

    5. DECLARE_DYNCREATE(class_name)

    该宏也往类中引入了DECLARE_DYNAMIC宏所引入的那三个成员。除此之外,它还另外引入唯一成员:

    static CObject* PASCAL CreateObject();

    该宏引入的成员在IMPLEMENT_DYNCREATE里初始化和呈现。

    6. IMPLEMENT_DYNCREATE(class_name, base_class_name)

    该宏自然是初始化和呈现由DECLARE_DYNCREATE引入的成员了。

    咱们看看CreateObject的呈现:

    CObject* PASCAL class_name::CreateObject()
    {
        return new class_name;
    }

    参数是如此简单,它就用CObject类里重载的new操作符创建唯一该类类别的对象。

    7. _DECLARE_DYNCREATE(class_name)

    该宏引入了和DECLARE_DYNCREATE引入的四个成员差不多的成员。唯一的区别是该宏引入的静态成员class##class_name前面没有const修饰符。

    8. DECLARE_SERIAL(class_name)

    该宏引入了和_DECLARE_DYNCREATE所引入的相同的四个成员,另外它还多了这么一句:

    AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);

    原来是把重载操作符operator>>的参数当作该类的友元。于是在操作符参数operator>>中就能够来访该类的成员了。

    9. IMPLEMENT_SERIAL(class_name, base_class_name, wSchema)

    该宏初始化了成员变量:

    CRuntimeClass class_name::class##class_name=
    {
    #class_name,
    
    sizeofclass class_name),
    
    wSchema,
    
    class_name::CreateObject),
    
    RUNTIME_CLASS(base_class_name),
    
    NULL
    
    };

    //在那里,class##class_name前面是没有const修饰符的。

    该宏还呈现了下列参数:

    CObject* PASCAL class_name::CreateObject()
    {
        return new class_name;
    }
    
    CRuntimeClass* class_name::GetRuntimeClass() const
    {
        return RUNTIME_CLASS(class_name);
    }
    
    CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb)
    {
        pOb=(class_name*)ar.ReadObject(RUNTIME_CLASS(class_name));
        return ar;
    }

    该宏还声明了唯一参数原型:

    AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name));

    参考链接:https://blog.csdn.net/liubing8609/java/article/details/84673631

  • 相关阅读:
    ubuntu配置apache支持sqlite数据库
    linux中的(),(()),[],[[]],{}的作用
    javascript问题积累
    羞愧的开始,成熟的开始,努力的开始
    asp发送邮件代码
    css&html的问题积累
    应用phpcms时遇到的问题及smarty标签的应用
    js正则积累
    产生一个int数组,长度为100,并向其中随机插入1100,并且不能重复。按照数组下标输出结果。
    不同项目之间的基础dll共用问题
  • 原文地址:https://www.cnblogs.com/2018shawn/p/13036984.html
Copyright © 2011-2022 走看看