知道有IsKindOf这么个函数,用来检测:(1)对象是否属于指定的类,(2)对象是否属于指定类派生的类,但是一直没用过,今天用了下,提示错误error C2039: 'classXXX' : is not a member of 'XXX',查了很多资料,才把它搞明白,记录如下:
1、对使用IsKindOf这个函数的类要在.h文件夹里定义DECLARE_DYNAMIC或DECLARE_SERIAL宏
- class CDlgTest : public CDialog
- {
- DECLARE_DYNAMIC( CDlgTest )
- // Construction
- public:
- CDlgTest(CWnd* pParent = NULL); // standard constructor
- ...
- ...
- };
2、需要在.cpp文件中加入IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL宏
- IMPLEMENT_DYNAMIC(CDlgTest, CDialog)
- CDlgTest::CDlgTest(CWnd* pParent /*=NULL*/)
- : CDialog(CDlgTest::IDD, pParent)
- {
- ...
- }
3、使用时,CDlgTest dlg;
if(dlg.IsKinfOf(CDialog))...
随后又研究了一下这几个宏,也算明白了IsKindOf的实现原理,做下简单记录:
1、DECLARE_DYNAMIC宏
- #define DECLARE_DYNAMIC(class_name)/
- public:/
- static CRuntimeClass class##class_name;/
- virtual CRuntimeClass* GetRuntimeClass() const;
2、IMPLEMENT_DYNAMIC宏
- #define IMPLEMENT_DYNAMIC(class_name,bass_class_name)/
- _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)
- #define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)/
- static char _lpsz##class_name[]= #class_name;/
- CRuntimeClass class_name::class##class_name = {/
- _lpsz##class_name,sizeof(class_name),wSchema,pfnNew,/
- RUNTIME_CLASS(base_class_name),NULL};/
- static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);/
- CRuntimeClass* class_name::GetRuntimeClass() const/
- { return &class_name::class##class_name;}
3、IsKindOf函数的实现
- BOOL CObject::IsKindof(const CRuntimeClass *pClass) const
- {
- CRuntimeClass* pClassThis=GetRuntimeClass();
- while(pClassThis != NULL)
- {
- if(pClassThis==pClass)
- return TRUE;
- pClassThis=pClassThis->m_pBaseClass;
- }
- return FALSE;
- }
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".