C++

C++ RTTI(Run-Time Type Information) 총정리

수달정보보호 2024. 4. 19. 19:57

1. RTTI의 개념

C++에서 RTTI(Run-time type information)는 런타임에 개체의 데이터 유형에 대한 정보를 노출하는 메커니즘으로, 하나 이상의 가상 기능을 가진 클래스에만 사용할 수 있다. 이를 통해 프로그램 실행 중에 객체의 유형을 결정할 수 있다.

'런타임 캐스트' 라는 개념이 있는데, 이것은 캐스트가 유효한지 검사하는 것이다. 포인터나 참조를 사용하여 객체의 런타임 유형을 확인하는 가장 간단한 접근 방식이라 할 수 있다. 이는 기본 클래스에서 파생된 유형으로 포인터를 캐스팅해야 할 때 특히 유용하다. 클래스의 상속 계층 구조를 다룰 때 일반적으로 객체의 캐스팅이 필요하다. 이런 캐스트에는 두 가지 유형이 존재한다.


① 업캐스팅: 파생된 클래스 객체의 포인터 또는 참조를 기본 클래스 포인터로 취급하는 경우
② 다운캐스팅: 기본 클래스 포인터 또는 참조가 파생 클래스 포인터로 변환되는 경우


그런데 특별히 dynamic_cast의 경우, 상속 계층에서 기본 클래스 포인터를 자식 클래스로 다운캐스팅하는 데 사용된다. 성공적인 캐스팅 시 변환된 유형의 포인터를 반환하지만, 원하는 하위 클래스 유형이 아닌 객체 포인터와 같은 잘못된 유형을 캐스팅하려고 하면 실패한다.

예를 들어, dynamic_cast는 RTTI를 사용하고 기본 클래스 B에 가상 함수가 없기 때문에 "can not dynamic_cast 'b' to 'class D'" 오류와 함께 프로그램이 실패한다.

 

예시:

// C++ program to demonstrate
// Run Time Type Identification(RTTI)
// but without virtual function 

#include <iostream>
using namespace std;

// initialization of base class
class B {};

// initialization of derived class
class D : public B {};

// Driver Code
int main()
{
     B* b = new D; // Base class pointer
     D* d = dynamic_cast<D*>(b); // Derived class pointer
     if (d != NULL)
          cout << "works";
     else
          cout << "cannot cast B* to D*";
     getchar(); // to get the next character 
     return 0;
}

 

위 프로그램에서 base 클래스 B에 virtual 함수를 추가하면 정상적으로 작동하게 될 것이다.

 

// C++ program to demonstrate
// Run Time Type Identification successfully
// With virtual function

#include <iostream>
using namespace std;

// Initialization of base class
class B {
     virtual void fun() {}
};

// Initialization of Derived class
class D : public B {
};

// Driver Code
int main()
{
     B* b = new D; // Base class pointer
     D* d = dynamic_cast<D*>(b); // Derived class pointer
     if (d != NULL)
          cout << "works";
     else
          cout << "cannot cast B* to D*";
     getchar();
     return 0;
}

 

출력:

works

 

728x90