IsKindOf()函数

来源:互联网 发布:手机赚钱软件,提现微信 编辑:程序博客网 时间:2024/05/21 10:31

知道有IsKindOf这么个函数,用来检测:(1)对象是否属于指定的类,(2)对象是否属于指定类派生的类,但是一直没用过,今天用了下,提示错误error C2039: 'classXXX' : is not a member of 'XXX',查了很多资料,才把它搞明白,记录如下:

1、对使用IsKindOf这个函数的类要在.h文件夹里定义DECLARE_DYNAMIC或DECLARE_SERIAL宏

[cpp] view plaincopy
  1. class CDlgTest : public CDialog  
  2. {  
  3.     DECLARE_DYNAMIC( CDlgTest )  
  4. // Construction  
  5. public:  
  6.     CDlgTest(CWnd* pParent = NULL);   // standard constructor  
  7.     ...  
  8.     ...  
  9. };  

2、需要在.cpp文件中加入IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL宏

[cpp] view plaincopy
  1. IMPLEMENT_DYNAMIC(CDlgTest, CDialog)  
  2.   
  3. CDlgTest::CDlgTest(CWnd* pParent /*=NULL*/)  
  4.     : CDialog(CDlgTest::IDD, pParent)  
  5. {  
  6.     ...  
  7. }  

3、使用时,CDlgTest dlg;

                 if(dlg.IsKinfOf(CDialog))...

 

随后又研究了一下这几个宏,也算明白了IsKindOf的实现原理,做下简单记录:

1、DECLARE_DYNAMIC宏

[cpp] view plaincopy
  1. #define DECLARE_DYNAMIC(class_name)/      
  2. public:/  
  3.     static CRuntimeClass class##class_name;/       
  4.      virtual CRuntimeClass* GetRuntimeClass() const;  

2、IMPLEMENT_DYNAMIC宏

[cpp] view plaincopy
  1. #define IMPLEMENT_DYNAMIC(class_name,bass_class_name)/  
  2.        _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)  
  3.   
  4. #define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)/  
  5.     static char _lpsz##class_name[]= #class_name;/  
  6.     CRuntimeClass class_name::class##class_name = {/  
  7.         _lpsz##class_name,sizeof(class_name),wSchema,pfnNew,/  
  8.             RUNTIME_CLASS(base_class_name),NULL};/  
  9.     static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);/  
  10.     CRuntimeClass* class_name::GetRuntimeClass() const/  
  11.         { return &class_name::class##class_name;}  

3、IsKindOf函数的实现

[cpp] view plaincopy
  1. BOOL CObject::IsKindof(const CRuntimeClass *pClass) const     
  2. {     
  3.     CRuntimeClass* pClassThis=GetRuntimeClass();     
  4.     while(pClassThis != NULL)     
  5.     {     
  6.         if(pClassThis==pClass)     
  7.             return TRUE;     
  8.         pClassThis=pClassThis->m_pBaseClass;     
  9.     }     
  10.     return FALSE;     
  11. }     

4、单行宏的定义

定义单行宏:主要有以下三种用法.

   1) 前加##或后加##,将标记作为一个合法的标识符的一部分.注意,不是字符串.多用于多行的宏定义中.例如:
#define A(x)  T_##x
则 int A(1) = 10; //等效于int T_1 = 10;
#define A(x)  Tx##__
则 int A(1) = 10; //等效于int T1__ = 10;
   2) 前加#@,将标记转换为相应的字符,注意:仅对单一标记转换有效
 #define B(x) #@x
 则B(a)即 'a',B(1)即 '1'.但B(abc)却不甚有效.
   3) 前加#,将标记转换为字符串.
 #define C(x) #x
 则C(1+1) 即 "1+1".
原创粉丝点击