2009년 01월 18일
CRuntimeClass - 객체 자료형 검사
CRuntimeClass에는 C++의 RTTI에서 dynamic_cast 연산자를 통해 Rum-time에 객체 자료형 검사를 가능하게 하는 기능을 갖추고 있습니다. CObject 클래스의 IsKindOf 멤버 함수를 사용하면 되는데 이에 대해서 알아보도록 하겠습니다.


CObject::IsKindOf

Tests this object's relationship to a given class.

BOOL IsKindOf(   const CRuntimeClass* pClass ) const;
pClass

A pointer to a CRuntimeClass structure associated with your CObject-derived class.

Nonzero if the object corresponds to the class; otherwise 0.

This function tests pClass to see if (1) it is an object of the specified class or (2) it is an object of a class derived from the specified class. This function works only for classes declared with the DECLARE_DYNAMIC, DECLARE_DYNCREATE, or DECLARE_SERIAL macro.

Do not use this function extensively because it defeats the C++ polymorphism feature. Use virtual functions instead.



우선, MSDN에서 이 함수를 설명하는 부분을 살펴보면 인자로 들어온 pClass(CRuntimeClass의 객체)와 현재 클래스와의 관계를 테스트하는데 사용한다고 합니다. 이때 서로 같으면 0이 아닌값 (TRUE)를 반환하며 같지 않으면 0을 반환합니다. 이 함수의 검사 대상인 pClass는 이 함수를 호출한 클래스의 CRuntimeClass 객체 일 수도 있고 또는 이 함수를 호출한 클래스를 상속받은 하위 클래스의 CRuntimeClass 객체일 수도 있다는 것입니다. ( 이 두 경우 모두 이 함수의 결과는 참을 반환 합니다. ) 이 함수는 오직 DECLARE_DYNAMIC, DECLARE_DYNCREATE, or DECLARE_SERIAL macro를 선언한 클래스에서만 사용이 가능합니다.
이 함수는 C++의 다형성 특징을 약화 시키기 때문에 광범위하게 사용되지는 않습니다. 대신 가상함수를 사용합니다. (이 부분에서 이 함수가 다형성 특징을 약화시키고 그 때문에 가상함수를 대신 사용하라는데 어떤 뜻인지 잘 모르겠네요 ㅡㅡ?)

※ 어설픈 영어 실력으로 인해 오역이 있을 수 있습니다.

위 설명을 예제 코드로 만들어서 테스트 해 보면 아래와 같습니다. 테스트 방법은 일단 Derived 클래스의 객체를 생성 한 후 첫번째로 Derived 클래스의 상위 클래스인 Base 클래스의 CRuntimeClass 객체를 인자로 넘겨 봅니다. 두번째는 Derived 클래스 자신의 CRuntimeClass객체를 인자로 넘겨보도 세번째로는 전혀 다른 클래스의 CRuntimeClass객체를 넘겨 봅니다. 위 MSDN의 설명데로 예제를 잘 만들었다면 결과는 아래 주석(// 이 내용이 출력 됩니다.)을 달아 놓은 부분의 문장이 콘솔에 출력되어야겠죠?

// IsKindOf.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

class Base : public CObject
{
 DECLARE_DYNAMIC(Base)

public:
};
IMPLEMENT_DYNAMIC(Base, CObject)

class Derived : public Base
{
 DECLARE_DYNAMIC(Derived)
};
IMPLEMENT_DYNAMIC(Derived, Base)

class Other : public CObject
{
 DECLARE_DYNAMIC(Other)

public:
};
IMPLEMENT_DYNAMIC(Other, CObject)

int _tmain(int argc, _TCHAR* argv[])
{
 Base* p = new Derived;
 
 if(p->IsKindOf(RUNTIME_CLASS(Base)))
  _tprintf(_T("p객체는 Base 클래스의 하위 클래스 또는 Base 클래스 입니다.\n"));   // 이 내용이 출력 됩니다.
 else
  _tprintf(_T("p객체는 Base 클래스의 하위 클래스 또는 Base 클래스가 아닙니다.\n"));

 if(p->IsKindOf(RUNTIME_CLASS(Derived)))
  _tprintf(_T("p객체는 Derived 클래스의 하위 클래스 또는 Derived 클래스 입니다.\n"));  // 이 내용이 출력 됩니다.
 else
  _tprintf(_T("p객체는 Derived 클래스의 하위 클래스 또는 Derived 클래스가 아닙니다.\n"));

 if(p->IsKindOf(RUNTIME_CLASS(Other)))
  _tprintf(_T("p객체는 Other 클래스의 하위 클래스 또는 Other 클래스 입니다.\n"));
 else
  _tprintf(_T("p객체는 Other 클래스의 하위 클래스 또는 Other 클래스가 아닙니다.\n"));  // 이 내용이 출력 됩니다.

 delete p;

 return 0;
}


* 실행 결과

실행 결과를 보면 의도한데로 잘 나오네요. 위 내용을 정리해보면 IsKindOf 함수는 Run-time에 객체의 자료형을 검사해 주는데 IsKindOf함수는 호출한 클래스 자신의 자료형 뿐만 아니라 상위 클래스에 대해서도 참을 반환 하는 것을 확인 할 수 있습니다.


* 참고 문헌

    윈도우즈 MFC 프로그래밍 : 원리에서 활용까지 (정보문화사)

* 예제 프로젝트

    IsKindOf.zip
    
by greenfrog | 2009/01/18 20:34 | C++ / WIN32 / MFC | 트랙백 | 덧글(0)
트랙백 주소 : http://greenfrog7.egloos.com/tb/1316331
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글



<< 이전 페이지 | 다음 페이지 >>