ItemType과 업캐스팅/다운캐스팅

Jaemyeong Lee·2024년 12월 13일

게임 서버1

목록 보기
56/220

이 Step에서 다루는 것

  • 업캐스팅(자식 -> 부모)과 다운캐스팅(부모 -> 자식)의 차이
  • 다운캐스팅 시 안전하게 타입을 확인하는 방법
  • ItemType 기반 분기와 dynamic_cast 기반 분기의 선택 기준

학습 목표

  • 왜 업캐스팅은 자연스럽고, 다운캐스팅은 검증이 필요한지 설명할 수 있다.
  • dynamic_castItemType + static_cast를 상황에 맞게 선택할 수 있다.

업캐스팅(Upcasting): 안전하고 자연스러운 변환

  • WeaponItem이므로 Weapon* -> Item*는 암시적으로 허용됩니다.
  • 업캐스팅의 목적은 “여러 자식 타입을 부모 타입 하나로 통합 관리”하는 것입니다.
Item* item = new Weapon(); // 업캐스팅 (암시적)
item->PrintInfo();         // 가상 함수면 실제 Weapon 버전 호출

다운캐스팅(Downcasting): 반드시 타입 검증이 필요

  • Item*가 항상 Weapon*를 가리키는 건 아닙니다.
  • 그래서 Item* -> Weapon*은 암시적으로 허용되지 않으며, 강제 캐스팅은 위험합니다.

위험한 예:

Weapon* w = (Weapon*)item; // ❌ 실제로 Armor일 수도 있음 (UB 위험)

방법 A (권장): dynamic_cast로 런타임 검증

if (Weapon* w = dynamic_cast<Weapon*>(item)) {
    int dmg = w->GetDamage();
} else if (Armor* a = dynamic_cast<Armor*>(item)) {
    int def = a->GetDefence();
}

포인트:

  • 맞는 타입이면 포인터를 반환하고, 아니면 nullptr를 반환합니다.
  • 그래서 다운캐스팅에서는 dynamic_cast + 널 체크 조합이 안전합니다.
  • 단, dynamic_cast를 쓰려면 기반 클래스(Item)가 다형 타입이어야 합니다.
    (예: virtual 함수가 최소 하나 필요)

방법 B: ItemType + static_cast (규칙을 엄격히 지킬 때)

if (item->GetItemType() == IT_Weapon) {
    Weapon* w = static_cast<Weapon*>(item);
    int dmg = w->GetDamage();
} else if (item->GetItemType() == IT_Armor) {
    Armor* a = static_cast<Armor*>(item);
    int def = a->GetDefence();
}

주의:

  • ItemType 값과 실제 객체 타입이 어긋나면 바로 위험해집니다.
  • 즉, 이 방식은 “태그와 실제 타입이 항상 동기화된다”는 강한 설계 규칙이 필요합니다.

실전 선택 기준

  • 공통 행동 호출: 가상 함수(virtual) 우선
  • 타입 전용 데이터 접근:
    • 기본은 dynamic_cast (안전성 우선)
    • 성능/RTTI 정책 등 이유가 명확할 때만 ItemType + static_cast

체크 질문 (스스로 답해보기)

  • 업캐스팅은 왜 암시적으로 허용될까?
  • 다운캐스팅에서 C-Style 캐스팅이 위험한 이유는?
  • dynamic_castItemType + static_cast의 트레이드오프는 무엇일까?

profile
李家네_공부방

0개의 댓글