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);
     }
    
    

     

  • 相关阅读:
    opencv MAT数据操作
    浅谈模式识别中的特征提取
    设置Mysql的连接超时参数
    win7下怎样设置putty免用户名密码登陆
    正则表达式简明参考
    利用 canvas 破解 某拖动验证码
    wamp环境中mysql更改root密码
    Python读写文件
    Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
    如何改变placeholder的颜色
  • 原文地址:https://www.cnblogs.com/wang-can/p/3303520.html
Copyright © 2011-2022 走看看