Runtime Type Information

RTTI란

  • C++ 컴파일러 내에 있는 객체의 타입 정보를 알아내는 기능
  • 런타임에서 포인터가 가리키는 객체의 타입을 알 수 있게 해주는 방법
    • 객체의 타입을 런타임에서 결정할 수 있도록 허용
    • 메모리 상주 객체에 타입 정보 추가
    • 런타임에서 객체의 캐스팅이 유효한지 알아내기 위해, 객체를 특정 타입으로 결정한다
  • 가상 함수를 가지고 있는 클래스에 대해서 사용 가능
    • vtable을 참조해서 적절한 타입의 클래스를 확인해야 하기 때문

RTTI의 목적

  • 하나의 공통 기초 클래스로부터 상속된 클래스 계층이 있다고 가정할 때, 이 계층에 속한 클래스들의 어떤 객체를 기초 클래스 포인터가 지시하도록 설정할 수 있다
  • 런타임에서 A 타입에서 B 타입으로 변경할 때 정보가 필요하기 때문
    • 컴파일시간에 타입 변환이 이루어진다면 RTTI가 필요없다.
    • 컴파일 단계에서 특정 타입으로 확정할 수 있고 그 타입을 확인할 수 있기 때문이다.

예제

// case 1
// 가상함수가 없는 경우
#include <iostream>

class Base { void C() {} };
class MAN : public Base { void A() {} };
class WOMAN : public Base { void B() {} };

int main()
{
  Base* base_m = new MAN();
  Base* base_w = new WOMAN();

  // 아래 코드는 둘다 class Base를 출력한다
  cout << typeid(*base_m).name();
  cout << typeid(*base_w).name();

	return 0;
}
  • 위의 코드의 경우, virtual로 선언된 함수가 없으므로 가상 함수 테이블에 없어 RTTI 정보를 가질 수 없다
    • 단형성 클래스들의 상속 계층일 뿐
// case 2
// 가상 함수가 있는 경우
#include <iostream>

class Base 
{
	void C() {}
	virtual void GO() {}
};
class MAN : public Base 
{ 
	void A() {}
	virtual void GO() {}
};
class WOMAN : public Base 
{ 
	void B() {}
	virtual void GO() {}
};
// 위의 class 들이 virtual method를 가지게 되었다.

int main()
{
	Base* base_m = new MAN();
	Base* base_w = new WOMAN();
  // class WOMAN 출력
	std::cout << typeid(*base_w).name() << std::endl;
  // class MAN 출력
	std::cout << typeid(*base_m).name() << std::endl;

	return 0;
}

dynamic_cast

  • 다형 형식을 변환하는 데 사용
  • 포인터가 지시하는 객체형이 무엇인지는 알려주지 않음
    • 그 객체 주소를 특정형의 포인터에 안전하게 대입가능한지 알려줌

typeid

  • 개체의 정확한 형식을 식별하는 데 사용
  • 두 객체의 데이터형이 같은지 확인 가능
  • 객체의 데이터형을 식별하는 하나의 값을 반환함으로서 확인
    • 클래스의 이름, 객체로 평가되는 식(??) 등

typeinfo

  • typeid 연산자에서 변환된 형식 정보를 저장하는 데 사용
  • 어떤 특별한 데이터형에 대한 정보를 저장
  • 데이터형을 비교할 수 있도록 ==와 != 연산자 오버로딩
  • typeinfo.h 헤더 포함해야 사용 가능

출처

Categories: ,

Updated: