Programming Language/C,C++

C++] RTTI(Run-Time Type Information)

TwinParadox 2017. 6. 2. 00:00
728x90




RTTI(Run-Time Type Information)

실행 중 객체의 타입과 관련된 정보를 알아내는 기법

실행 중 포인터가 가리키는 객체의 실제 타입을 알아야 하는 경우,

클래스가 상속 관계에 있을 때 포인터가 가리키는 객체가 파생클래스의 객체인지

기본클래스의 객체인지 판단해야 하는 경우, RTTI 기법을 이용해 알아낼 수 있다.

RTTI 활용을 위해서는 typeinfo 헤더를 포함시켜야 함.



type_info 클래스는 typeid 연산자에 의해 반환되는 정보로,

타입 이름과 같은 타입에 관한 정보를 가진 클래스임


1
2
3
4
5
6
7
8
9
class type_info
{
public:
    bool operator==(const type_info& rhs);
    bool operator!=(const type_info& rhs);
    int before(const type_info& rhs);
    const char* name();
    const char* raw_name();
};
cs


==, !=는 두 객체가 특정 타입인지 같은 타입인지 검사하는데 주요하게 사용하며

name()은 타입의 이름을 문자열로 반환함


typeid 연산

프로그램 실행 중 객체의 타입정보(type_info&)를 반환한다.

상속 관계에 있는 객체에 대해 typeid를 사용하려면 반드시 기본 클래스에 가상 함수가 있어야 함.


dynamic_cast 연산

업캐스팅된 포인트를 다운 캐스팅할 경우 반드시 캐스팅 타입을 준다.

캐스팅 타입을 잘못 주면 오류가 발생하여 프로그램이 강제 종료되는데,

dynamic_cast 연산을 사용하면 유효한지 판단해 프로그램 강제 종료를 방지할 수 있다.

피연산자로 주어진 객체를 다른 타입으로 캐스팅하며, 유효하지 않는 캐스팅이면 NULL 포인터를 반환



RTTI를 활용한 실행 중 포인터가 가리키는 객체 타입 판별 예제


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <typeinfo>
using namespace std;
 
class DObject
{
public:
    virtual void draw() { cout << ""; }
};
 
class Circle : public DObject
{
public:
    void draw() { cout << "@@@@"; }
    void paintCircle() { cout << "원"; }
};
 
class Rect : public DObject
{
public:
    void draw() { cout << "****"; }
};
 
class Line : public DObject
{
public:
    void draw() { cout << "----"; }
};
 
bool isCircle(DObject *p)
{
    if (typeid(*p) == typeid(Circle))
        return true;
    else
        return false;
}
 
int main()
{
    DObject *list[4= { new Rect(), new Circle(), new Line(), new Circle() };
    for (int i = 0; i < 4; i++)
    {
        if (isCircle(list[i]))
        {
            cout << i << " ";
            cout << typeid(*list[i]).name() << ' ';
            Circle *= dynamic_cast<Circle*>(list[i]);
            p->paintCircle();
            cout << endl;
        }
    }
    for (int i = 0; i < 4; i++)
        delete list[i];
}
cs



728x90