[DAY31] Test Recap(3) : RTTI, C++ Casting

베리투스·2025년 9월 16일

TIL: Today I Learned

목록 보기
32/93

오늘은 C++의 RTTI와 4대 캐스팅 연산자에 대해 공부했다. 개념 자체는 알고 있었지만, 모의 면접을 통해 dynamic_cast가 동작하기 위한 정확한 조건을 내가 잘못 알고 있었다는 것을 깨달았다. 🤯 단순히 '가상 함수가 필요하다'를 넘어, 왜 그것이 '다형적(polymorphic) 클래스'라는 조건으로 이어지는지 명확히 이해하게 되었다. 런타임에 타입을 확인하는 것이 어떤 의미인지, 그리고 왜 C++이 다양한 캐스팅 연산자를 제공하는지 그 의도를 파악할 수 있었던 시간이었다.


📌 목표

  • RTTI의 개념과 dynamic_cast, typeid 연산자의 용도 이해하기
  • static_cast, dynamic_cast, const_cast, reinterpret_cast의 차이점 설명하기
  • dynamic_cast가 성공하기 위한 필수 조건 정확히 알기

📖 이론

1. RTTI (Run-Time Type Information)

RTTI는 이름 그대로 '런타임 타입 정보'를 의미한다. 프로그램이 실행되는 도중에 객체의 실제 타입을 확인할 수 있게 해주는 C++의 기능이다.

  • dynamic_cast: 런타임에 안전하게 다운캐스팅을 시도한다. 기반 클래스 포인터가 실제로 가리키는 객체가 다운캐스팅하려는 파생 클래스 타입이 맞는지 확인한다.
    • 성공 시: 유효한 포인터(또는 참조) 반환
    • 실패 시: nullptr (포인터의 경우) 또는 bad_cast 예외 (참조의 경우)를 발생시킨다.
  • typeid: 객체의 정확한 타입 정보를 담고 있는 type_info 객체를 반환한다. 주로 두 객체의 타입이 완전히 같은지 비교할 때 사용한다.

이 기능들이 작동하려면, 컴파일러가 타입 정보를 vtable 같은 곳에 저장해둬야 한다. 그래서 RTTI는 하나 이상의 가상 함수를 가진 클래스(즉, 다형적 클래스)에서만 제대로 동작한다.

2. C++ 4대 캐스팅 연산자

C-스타일 캐스팅 (type)value는 너무 강력하고 의도가 불분명해서, C++에서는 용도에 따라 4가지 캐스팅 연산자를 제공한다.

  • static_cast: 컴파일 타임에 타입을 변환한다. 논리적으로 변환 가능한 경우에 사용하며(예: int를 float으로, 파생 클래스 포인터를 기반 클래스 포인터로), 런타임 타입 체크는 하지 않는다.
  • dynamic_cast: 위에서 설명한 RTTI를 이용한 런타임 타입 체크 캐스팅. 안전한 다운캐스팅에 사용된다.
  • const_cast: 객체의 constvolatile 속성을 제거할 때만 사용한다. 타입 자체를 바꾸지는 않는다.
  • reinterpret_cast: 가장 위험한 캐스팅. 포인터나 정수형 변수 간의 비트 수준 재해석 변환을 수행한다. 관련 없는 타입 간의 변환이라 매우 조심해서 써야 한다. ⚠️

⚠️ 실수

  • dynamic_cast는 추상 클래스에만 사용할 수 있다고 생각했다.

    • (X) dynamic_cast를 쓰려면 기반 클래스가 반드시 추상 클래스여야 한다.
    • (O) 기반 클래스는 다형적(polymorphic) 클래스여야 한다. 즉, 가상 함수가 하나라도 포함되어 있으면 된다. 가상 소멸자도 가상 함수이므로, 가상 소멸자만 있어도 dynamic_cast는 사용 가능하다.
  • 기반 클래스 포인터가 기반 클래스 객체를 가리킬 때, dynamic_cast가 실패하는 이유를 조건 부족 탓으로만 돌렸다.

    • (X) Base* p = new Base(); 일 때 dynamic_cast<Derived*>(p)가 실패하는 이유는 Base 클래스에 가상 함수가 없기 때문이다.
    • (O) 가상 함수 유무도 중요하지만, 더 근본적인 원인은 포인터가 가리키는 실제 객체가 Derived가 아니기 때문이다. dynamic_cast는 "이 포인터가 실제로 Derived 타입의 객체를 가리키고 있니?"라고 런타임에 묻는 것과 같다. Base 객체는 Derived 객체가 아니므로, 다형성 조건이 갖춰져도 캐스팅은 당연히 실패하고 nullptr를 반환한다.

✅ 핵심 요약

개념설명비고
RTTI런타임에 객체의 실제 타입을 확인할 수 있는 기능.dynamic_cast, typeid가 핵심 연산자.
dynamic_cast런타임 타입 체크를 통해 안전하게 다운캐스팅한다.다형적 클래스에만 사용 가능. (가상 함수 필수)
static_cast컴파일 타임에 논리적으로 관련된 타입 간 변환을 수행한다.런타임 비용이 없지만, 잘못된 다운캐스팅은 위험.
const_cast객체의 const 또는 volatile 한정자를 제거한다.타입 자체를 바꾸는 것이 아님.
reinterpret_cast관련 없는 타입 간의 비트 수준 재해석 변환을 수행한다.매우 위험하며, 거의 사용하지 않음. 💣
profile
Shin Ji Yong // Unreal Engine 5 공부중입니다~

0개의 댓글