Search
Duplicate

C++에서의 몇 가지 의문 사항에 대한 정리 (3) RTTI

Category
S/W 엔지니어
Tags
C++
RTTI
typeid
type_info
dynamic_cast
Created time
2004/11/02
MFC를 쓰며 언제나 "저게 뭐야?"하고 지나쳐왔던 RUNTIME_CLASS, DECLARE_DYNAMIC등의 매크로. 어디에, 왜, 언제쓰는지도 모른 채 그냥 지나쳐왔던 그 내용들..이것들이 실행 시 인스턴스의 실제 타입을 알아내는 데 이용하는 MFC의 메카니즘이라는 것을 이제야 알게되었다. 그것도 MFC가 아니라, C++을 다시 보면서.

RTTI(Run-Time Type Identification 혹은 Run-Time Type Information)

은 C++에서 기본적으로 지원한다. 근디, MFC에서는 C++이 지원하는 놈들을 안쓰고 위의 매크로 등을 통해 독자적으로 이 기능을 지원하는데, 왜 그런지는 낭중에 알아보기로 해야겠다. (새로 배우기도 빡신데, 찾기까지는 넘 힘들다.) Visual C++에서는 프로젝트 Setting 항목에서 C++ Language 탭의 "Enable RTTI"를 활성화해야 한다.

dynamic_cast 연산자

어떤 클래스 객체에 대한 포인터를, 그 클래스와 동일한 계통에 있는 다른 클래스의 포인터로 변경할 경우에 사용하거나, 어떤 클래스 객체에 대한 lvalue를, 그 클래스와 동일한 계통에 있는 다른 클래스의 레퍼런스로 변경할 경우에 사용한다.
다른 캐스트 연산자와는 달리, 런타임에 변환이 되고, 올바른 변환인지를 검사한다음, 올바를 경우에만 변환하기 때문에 다른 캐스트 연산자보다 안전하더라..
변환 실패의 경우, 포인터 타입에 대한 실패일 때는 0을 반환, 레퍼런스 타입에 대한 실패일 때는 예외를 던진다. 고로 언제나 변환 성공 여부에 대한 TEST 코드를 넣는 것이 신상에 좋더라..(예외 타입인 std:bad_cast를 참조하려면, <typeinfo> 헤더를 포함해야 한다.)
// 예: employee가 manager의 기반 클래스일 때(pE는 employee의 포인터, rE는 레퍼런스), manager* pM = dynamic_cast< manager* >(pE); //포인터 타입의 변환 manager& rM = dynamic_cast< manager& >(rE); //레퍼런스 타입의 변환
C++
복사

typeid 연산자

표현식(expression)으로써 타입이 무엇인지를 알아낼 수 있다. 여기서 표현식은 일반 타입이 될 수 있고, 가상 함수가 담긴 타입도 될 수 있는데, 그 표현식의 결과는 표현식 자체의 타입에 따라 달라지더라...
<typeinfo> 헤더를 포함해야 한다.
이 연산자의 반환 값은 type_info 클래스 타입이더라..
주로, type_info 클래스의 name() 함수(표현식의 타입 이름을 반환)와 == 연산자를 많이 이용하더라..

type_info 클래스

typeid 연산자가 반환하는 타입. 이 타입을 이용해서 타입 비교, 타입 이름 알아내기 등을 해낸다.
<typeinfo> 헤더를 포함해야 한다.
기본 생성자는 없으며, 복사 생성자와 복사 대입 연산자가 private 멤버이기 때문에, 사용자가 자신의 프로그램에서 따로 정의해서 사용할 수 없다. 오직 typeid 연산자를 통해서만 생성된다.
컴파일러마다 각기 달리 구현된다. 그러므로, 타입 이름 외에도 컴파일러에 따라 다른 종류의 정보가 담겨질 수 있다.

참고 자료

C++ Primer(Stan Lippman저, Addison-Wesley)