RTTI(RunTime Type Information)는 실행 시간에 객체들의 정보를 얻는 표준화된 방법을 제공합니다.
RTTI의 주요 구성 요소
- type_info 클래스 : 실행 시간에 확인하고자 하는 타입에 대한 정보 저장 클래스.
- typeid 연산자 : 객체 타입을 식별하고 반환하는 연산자 .
- dynamic_cast 연산자 : 실행 시간에 실제 객체 타입을 인식하여 형변환하는 연산자.
사용시 주의점
- 보통 컴파일러는 RTTI가 동작하지 않도록 설정되어 있습니다. RTTI가 동작하도록 옵션을 설정해야 합니다. (RTTI를 사용하지 않는 프로그램이 굳이 RTTI 코드를 포함할 필요가 없기 때문에...)
- 계층 구조상의 클래스 정보를 확인하기 위해서는 클래스에 virtual 함수가 있어야 합니다. ( 다형성을 사용하지 않는 기본 클래스의 RTTI는 별 의미가 없기 때문입니다.)
VS2008의 RTTI 설정 그림(프로젝트 메뉴의 속성 페이지)
RTTI 사용 예
#include <iostream>#include <typeinfo>
using namespace std;
class Parent
{
public :
virtual ~Parent() { }
};
class Child : public Parent
{
};
void main( )
{
Parent objParent;
Child objChild;
cout << typeid( objParent ).name() << endl;
cout << typeid( objChild ).name() << endl;
Parent *p = NULL;
p = new Parent;
cout << typeid( *p ).name() << endl;
p = new Child;
cout << typeid( *p ).name() << endl;
}
class Parent
class Child
class Parent
class Child
typeid() 연산자는 타입 정보 객체의 레퍼런스를 리턴합니다. 함수의 원형은 const type_info& typeid(type_name); 입니다. const type_info&를 반환합니다.
그래서 위 예제는 아래처럼 사용할 수 있습니다.( 더 복잡?하게..)
#include <iostream>#include <typeinfo>
using namespace std;
class Parent
{
public :
virtual ~Parent() { }
};
class Child : public Parent
{
};
void main( )
{
Parent objParent;
Child objChild;
const type_info& info1 = typeid( objParent );
cout << info1.name() << endl;
const type_info& info2 = typeid( objChild );
cout << info2.name() << endl;
Parent *p = NULL;
p = new Parent;
const type_info& info3 = typeid( *p );
cout << info3.name() << endl;
p = new Child;
const type_info& info4 = typeid( *p );
cout << info4.name() << endl;
}
- class Parent
class Child
class Parent
class Child
type_info 객체는 생성하거나 변경할 수 없습니다. 생성자가 private으로 접근할 수 없고 typeid()가 const 객체를 리턴하므로 변경할 수 없습니다. 정보를 얻는 용도로만 사용합니다.
type_info 클래스는 아래와 같은 멤버로 정의되어 있습니다.
public:
virtual ~type_info();
bool operator==(const type_info& rhs) const;
bool operator!=(const type_info& rhs) const;
int before(const type_info& rhs) const;
const char* name(__type_info_node* __ptype_info_node = &__type_info_root_node) const;
const char* raw_name() const;
private:
void *_m_data;
char _m_d_name[1];
...
};
그래서 객체 비교도 가능합니다.
#include <iostream>#include <typeinfo>
using namespace std;
class Parent
{
public :
virtual ~Parent() { }
};
class Child : public Parent
{
};
class Child2 : public Parent
{
};
void main( )
{
Parent *p1 = new Child;
Parent *p2 = new Child2;
Parent *p3 = new Child;
if( typeid( *p1 ) == typeid( *p2 ) )
cout << "같은 타입 객체" << endl;
else
cout << "다른 타입 객체" << endl;
if( typeid( *p1 ) == typeid( *p3 ) )
cout << "같은 타입 객체" << endl;
else
cout << "다른 타입 객체" << endl;
}
- 다른 타입 객체
같은 타입 객체
*p1과 *p2는 Child와 Child2 클래스 타입으로 서로 다릅니다. *p1과 *p3는 모두 Child 클래스 타입으로 같습니다. type_info 클래스가 제공하는 인터페이스를 사용하여 더 많은 기능을 수행할 수 있습니다.
RTTI는 객체들의 정보를 얻는 곳에만 사용하는 것이 좋습니다. 객체들을 비교, 구분하기 위해 RTTI를 난발하는 것은 프로그램 구조나 효율, 확장성 및 유연성 등에 좋지 않습니다. RTTI를 사용하여 객체를 비교하는 코드 대부분에 다형성을 이용하여 구현할 수 있습니다. RTTI는 객체의 간단한 정보를 얻기 위해서만 사용하세요.
댓글 없음:
댓글 쓰기