C++ 사총사 캐스팅

Jaemyeong Lee·2024년 10월 30일

게임 서버1

목록 보기
59/220

이 Step에서 다루는 것

  • C++의 4가지 캐스팅(static_cast, dynamic_cast, const_cast, reinterpret_cast)
  • 각 캐스팅의 목적/안전성/제약
  • 실전에서 “어떤 상황에 무엇을 써야 하는지” 판단 기준

학습 목표

  • C-Style 캐스팅 대신 목적에 맞는 C++ 캐스팅을 선택할 수 있다.
  • 다운캐스팅에서 왜 dynamic_cast가 기본 선택인지 설명할 수 있다.
  • const_cast/reinterpret_cast가 왜 고위험인지 설명할 수 있다.

static_cast: 일반적인 값 변환 + 컴파일타임 기준 변환

주 용도:

  • 숫자 타입 변환(int -> float)
  • 명확한 상속 관계에서의 변환(특히 업캐스팅)
float ratio = static_cast<float>(hp) / maxHp; // 값 변환
Player* p = static_cast<Player*>(knightPtr);  // 업캐스팅(예시)

주의:

  • 다운캐스팅(Player* -> Knight*)도 문법상 가능하지만
  • 런타임 타입 검증을 하지 않음 -> 틀리면 UB

dynamic_cast: 런타임 타입 검증이 필요한 다운캐스팅

전제:

  • 다형 타입(기반 클래스에 virtual 함수 최소 1개)
  • 상속 관계에서만 사용 가능
if (Weapon* w = dynamic_cast<Weapon*>(item)) {
    int dmg = w->GetDamage();
}

핵심:

  • 포인터 캐스팅 실패 시 nullptr
  • 참조 캐스팅 실패 시 std::bad_cast 예외
  • 안전성은 높고, 런타임 검사 비용이 조금 있음

const_cast: const/volatile 한정자만 조정

void UseMutable(char* p);

const char* src = "abc";
UseMutable(const_cast<char*>(src)); // 매우 위험할 수 있음

핵심:

  • 타입 자체를 바꾸는 캐스팅이 아니라 const 속성만 조정
  • 원래 객체가 truly const인 경우 수정하면 UB
  • 실무에선 API 경계/레거시 연동 같은 특수 상황에서만 제한적으로 사용

reinterpret_cast: 비트/주소를 다른 타입으로 해석

#include <cstdint>

std::uintptr_t addr = reinterpret_cast<std::uintptr_t>(ptr);

핵심:

  • 가장 저수준, 가장 위험
  • “의미 있는 타입 변환”이 아니라 “해석 방식 강제 변경”에 가깝다
  • 시스템/직렬화/특수 최적화 같은 저수준 코드에서만 신중하게 사용

사총사 캐스팅 한눈에 비교

캐스팅핵심 용도안전성/주의
static_cast일반 변환, 업캐스팅다운캐스팅 검증 없음(주의)
dynamic_cast안전한 다운캐스팅RTTI/virtual 필요, 실패 시 null/예외
const_castconst 한정자 조정truly const 수정 시 UB
reinterpret_cast저수준 비트/주소 해석 변경가장 위험, 극히 제한적으로 사용

실전 규칙(짧게)

  • 숫자/일반 변환 -> static_cast
  • 다운캐스팅 -> 기본은 dynamic_cast
  • const 제거 -> 정말 필요할 때만 const_cast
  • 메모리 해석 강제 변경 -> 마지막 수단으로 reinterpret_cast

profile
李家네_공부방

0개의 댓글