Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ RTTI(런타임 타입 정보)란? dynamic_cast와 가상 함수의 관계까지 예제로 이해하기

이번 글에서는 C++의 RTTI(Runtime Type Information, 런타임 타입 정보)에 대해 알아보겠습니다.

RTTI란 무엇인가?

RTTI는 프로그램이 실행 중(runtime)일 때 객체의 실제 자료형(data type)에 대한 정보를 노출해 주는 메커니즘입니다. 이를 활용하면 컴파일 시점이 아닌 실행 시점에 객체의 정확한 타입을 판별할 수 있습니다.

다만 중요한 조건이 있습니다. RTTI 기능은 해당 클래스에 최소 하나 이상의 가상 함수(virtual function)가 존재할 때만 사용할 수 있습니다. 즉, 다형성(polymorphism)을 갖춘 클래스여야 한다는 의미입니다.

가상 함수가 없으면 어떻게 될까?

다음 예제 코드는 가상 함수가 없는 상태에서 dynamic_cast를 사용하는 경우입니다. 이 코드는 컴파일되지 않고 다음과 같은 오류를 발생시킵니다.

“cannot dynamic_cast base_ptr (of type Base*) to type 'class Derived*' (Source type is not polymorphic)”

오류 메시지 그대로, 소스 타입이 다형적(polymorphic)이지 않기 때문에 변환이 불가능하다는 뜻입니다. 클래스에 가상 함수가 없으면 vtable(가상 함수 테이블)이 생성되지 않아 런타임에 실제 객체 타입을 식별할 수 없기 때문입니다.

예제 코드 1 — 실패하는 경우

#include<iostream>
using namespace std;

class Base { };

class Derived : public Base { };

int main() {
    Base *base_ptr = new Derived;
    Derived *derived_ptr = dynamic_cast<Derived*>(base_ptr);

    if(derived_ptr != NULL)
        cout<<"It is working";
    else
        cout<<"cannot cast Base* to Derived*";

    return 0;
}

위 코드는 Base 클래스에 가상 함수가 없으므로 컴파일 오류가 발생합니다.

예제 코드 2 — 가상 함수 추가 후 성공

이번에는 Base 클래스에 가상 함수를 하나 추가해 보겠습니다. 그러면 RTTI가 활성화되어 dynamic_cast가 정상적으로 동작합니다.

#include<iostream>
using namespace std;

class Base {
public:
    virtual void function() {
        // 빈 함수
    }
};

class Derived : public Base { };

int main() {
    Base *base_ptr = new Derived;
    Derived *derived_ptr = dynamic_cast<Derived*>(base_ptr);

    if(derived_ptr != NULL)
        cout<<"It is working";
    else
        cout<<"cannot cast Base* to Derived*";

    return 0;
}

실행 결과

It is working

정리

  • RTTI는 실행 시점에 객체의 실제 타입 정보를 제공하는 C++의 메커니즘입니다.
  • dynamic_casttypeid 같은 연산자가 RTTI를 활용하는 대표적인 예입니다.
  • RTTI가 동작하려면 클래스에 최소 하나의 가상 함수가 있어야 하며, 이는 곧 다형적 타입이어야 함을 의미합니다.