C++의 RTTI는 정말 편리하다.
프로그램 실행중에 변수의 자료형을 확인할 수 있으니 말이다.
RTTI는 C++ 표준서 및 MFC RTTI 지원 문서를 참고하자.
C++ RTTI : http://sweeper.egloos.com/2826160
MFC RTTI : http://anster.egloos.com/2173004
그런데 써본 사람들은 알겠지만, 이 MFC의 RUNTIME_CLASS() 매크로는 속도도 빠르고 좋은데
문제는 내포 클래스(혹은 중첩 클래스라고 말하기도 한다)에는 사용할 수 없다.
내포 클래스란...? http://initial4-blog.blogspot.kr/2012/06/c-study-512-part.html
내포 클래스는 용도에 따라서 매우 유용한 클래스인데, 이런 내포(중첩)클래스에서도 RTTI를 사용할 수 있도록 MFC의 RUNTIME_CLASS를 약간 수정해 보았다.
IMPLEMENT_DYNAMIC_NESTED() 의 사용방법은 다음과 같다.
IMPLEMENT_RUNTIME_GETRUNTHISCLASS(nesting_class, class_name, base_class_name)
=> nesting_class는 내부 클래스를 감싸는 외부 클래스
=> class_name은 외부 클래스 안에 있는 내포 클래스 즉, 중첩 클래스
=> base_class_name은 내포 클래스 즉, 중첩 클래스가 상속하고 있는 부모 클래스.
아래는 사용 예를 보여준다.
---------------- 헤더파일에 추가할 내용 ----------------
#define RUNTIME_CLASS_NESTED(nesting_class, class_name) ((CRuntimeClass*)(&nesting_class::class_name::class##class_name))
#if _MSC_VER >= 1600
#define IMPLEMENT_RUNTIME_GETRUNTHISCLASS(nesting_class, class_name, base_class_name)\
CRuntimeClass* nesting_class::class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS_NESTED(nesting_class, class_name); } \
CRuntimeClass* PASCAL nesting_class::class_name::GetThisClass() \
{ return RUNTIME_CLASS_NESTED(nesting_class, class_name); }
#else
#define IMPLEMENT_RUNTIME_GETRUNTHISCLASS(nesting_class, class_name, base_class_name)\
CRuntimeClass* nesting_class::class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS_NESTED(nesting_class, class_name); }
#endif
#ifdef _AFXDLL
#define IMPLEMENT_RUNTIMECLASS_NESTED(nesting_class, class_name, base_class_name, wSchema, pfnNew) \
CRuntimeClass* PASCAL nesting_class::class_name::_GetBaseClass() \
{ return RUNTIME_CLASS(base_class_name); } \
AFX_COMDAT const AFX_DATADEF CRuntimeClass nesting_class::class_name::class##class_name = { \
#class_name, sizeof(class nesting_class::class_name), wSchema, pfnNew, \
&nesting_class::class_name::_GetBaseClass, NULL }; \
IMPLEMENT_RUNTIME_GETRUNTHISCLASS(nesting_class, class_name, base_class_name)
#else
#define IMPLEMENT_RUNTIMECLASS_NESTED(nesting_class, class_name, base_class_name, wSchema, pfnNew) \
AFX_COMDAT const AFX_DATADEF CRuntimeClass nesting_class::class_name::class##class_name = { \
#class_name, sizeof(class nesting_class::class_name), wSchema, pfnNew, \
RUNTIME_CLASS(base_class_name), NULL }; \
IMPLEMENT_RUNTIME_GETRUNTHISCLASS(nesting_class, class_name, base_class_name)
#endif
#define IMPLEMENT_DYNAMIC_NESTED(nesting_class, class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS_NESTED(nesting_class, class_name, base_class_name, 0xFFFF, NULL)
---------------- 사용하는 방법 예제 ----------------
A.h
class CA : public CObject
{
public:
DECLARE_DYNAMIC(CA)
CA(){}
virtual ~CA(){}
private:
class CANested : public CObject
{
public:
DECLARE_DYNAMIC(CANested)
CANested() {}
virtual ~CANested() {}
};
};
A.cpp
IMPLEMENT_DYNAMIC(CA, CObject)
IMPLEMENT_DYNAMIC_NESTED(CA, CANested, CObject)