zoukankan      html  css  js  c++  java
  • MFC中的动态创建

    1、为了能够动态创建,程序必须维护一个CRuntimeClass的类,当需要去识别一个类的时候,就依次去查找这个链表,而这个是通过一组宏来实现的。因为是一个链表,所以就需要初始化,这个初始化在CObject中用稍有不同的宏来实现的。

    2、CRuntimeClass的结构:

    LPCSTR m_lpszClassName //类名

    int m_nObjectSize                    //类字节大小,不计算分配的内存

    UINT m_wSchema                    //一般为0xFFFF

    CObject* ( PASCAL* m_pfnCreateObject )( )      //一个函数指针,用来 动态创建对象

    CRuntimeClass* ( PASCAL* m_pfn_GetBaseClass )( )     //如果是动态加载的话,就指向基类的CRuntimeClass对象的指针,否则为null

    CRuntimeClass* m_pBaseClass              //如果是静态加载的话,就指向基类的CRuntimeClass对象的指针,否则为null

    CObject* CreateObject( );                //一个函数,用来创建类本身

    BOOL IsDerivedFrom( const CRuntimeClass* pBaseClass) const;//一个函数,用来判断是否继承自某个类

    3、这组宏就是DECLARE_DYNCREATE(class_name) 与 IMPLEMENT_DYNCREATE(class_name, base_class_name),其实在这组宏的内部还有一组宏,大家可以自己去查看,其实这里面的这组宏是来实现类型识别的。下面将展示将这组宏展开后的代码应该是如何的:

    #define DECLARE_DYNCREATE(class_name)所对应的代码
    
    protected: 
    	static CRuntimeClass* PASCAL _GetBaseClass(); 
    public: 
    	static const CRuntimeClass class##class_name; 
    	static CRuntimeClass* PASCAL GetThisClass(); 
    	virtual CRuntimeClass* GetRuntimeClass() const; 
    static CObject* PASCAL CreateObject();
    
    
    #define IMPLEMENT_DYNCREATE(class_name, base_class_name)所对应的代码
    
    CObject* PASCAL class_name::CreateObject() 
    		{ return new class_name; }
    CRuntimeClass* PASCAL class_name::_GetBaseClass() 
    		{ return RUNTIME_CLASS(base_class_name); } 
    	AFX_COMDAT const CRuntimeClass class_name::class##class_name = { 
    		#class_name, sizeof(class class_name), wSchema, pfnNew, 
    			&class_name::_GetBaseClass, NULL, class_init }; 
    	CRuntimeClass* PASCAL class_name::GetThisClass() 
    		{ return _RUNTIME_CLASS(class_name); } 
    	CRuntimeClass* class_name::GetRuntimeClass() const 
    		{ return _RUNTIME_CLASS(class_name); }
    
    
    假如这里有一个CView类
    则	#define DECLARE_DYNCREATE(CView)对应的翻译后的代码为:
    
    protected: 
    	//其中PASCAL是调用协议,此处声明了一个函数。
    	static CRuntimeClass* PASCAL _GetBaseClass();
     public: 
    	//此处声明一个CRuntimeClass的对象,来保存相应的类信息
    	static const CRuntimeClass classCView; 
    	//声明一个获得类本身的信息的一个函数
    	static CRuntimeClass* PASCAL GetThisClass(); 
    	//声明一个获得CRuntimeClass的结构
    	virtual CRuntimeClass* GetRuntimeClass() const; 
    	//声明一个可以动态创建类本身的函数
    	static CObject* PASCAL CreateObject();
    
    #define IMPLEMENT_DYNCREATE(CView, CWnd)所对应翻译后的代码为:
    
    //创建类本身的对象
    CObject* PASCAL CView::CreateObject() 
    {
    	 return new CView;
     }
    //获得基类的信息
    CRuntimeClass* PASCAL CView::_GetBaseClass() 
    { 
    	return RUNTIME_CLASS(base_class_name);
     } 
    //声明一个结构对象,并初始化
    AFX_COMDAT const CRuntimeClass CView::classCView = { 
    	"CView", sizeof(class CView), 0xFFFF, CView::CreateObject, 
    		&CView::_GetBaseClass, NULL, class_init }; 
    //获得该类的相应信息
    CRuntimeClass* PASCAL CView::GetThisClass() 
    {
    	 return _RUNTIME_CLASS(CView);
    } 
    获得该类的相应信息
    CRuntimeClass* class_name::GetRuntimeClass() const 
    {
    	 return _RUNTIME_CLASS(CView);
     }
    
    

     

  • 相关阅读:
    IOS-自定义返回按钮,保留系统滑动返回
    IOS-static cell 与 dynamic cell 混合使用
    IOS-快速集成检查更新
    IOS-如何优雅地拦截按钮事件(判断是否需要登录)
    IOS-更优雅地使用Static Cell
    Xcode8出现问题总结
    IOS-工程师Mac上的必备软件
    Minimum Sum of Array(map迭代器)
    C++ STL map
    Friends and Cookies(思维)
  • 原文地址:https://www.cnblogs.com/wang-can/p/3303520.html
Copyright © 2011-2022 走看看