C++ RTTI 활용 (완성): TSubclassOf 스타일로 타입 기반 객체 생성 구현하기 (4탄)

🚀 들어가며

이번 글에서는 C++ TSubclassOf 구현을 통해
타입 정보를 기반으로 객체를 생성하는 방법을 살펴봅니다.

이전 글에서 우리는 다음의 내용을 이해하고 구현했습니다.

이제 마지막 단계입니다.

❓ 타입을 “확인”하는 것을 넘어
👉 타입으로 “객체를 생성”할 수는 없을까?


🎯 이번 글의 목표

이번 글에서는 다음을 구현합니다:

  • 타입을 변수로 저장
  • 런타임에 객체 생성
  • Unreal Engine 스타일 구조 이해

👉 즉,

“클래스를 값처럼 다루는 시스템”


🧠 핵심 아이디어

지금까지는:

obj->Is(Player::StaticClass())
👉 타입 비교만 가능

이제 목표는:

TSubclassOf myClass = Player::StaticClass();
auto obj = Spawn(myClass);
👉 타입 → 객체 생성

🔥 해결 방법: 생성 함수 저장

C++에서는 “타입 자체”를 저장할 수 없기 때문에
👉 대신 생성 함수 포인터를 저장합니다.


🧩 TSubclassOf 구현 (기초)

using TSubclassOf = std::shared_ptr<class CraftObject>(*)();
👉 의미:

CraftObject를 생성하는 함수 포인터


⚙️ 클래스에 생성 함수 추가

#define TYPE_DECLARATIONS(Type, ParentType)                 \
public:                                                     \
    static std::shared_ptr<CraftObject> CreateInstance()    \
    {                                                       \
        return std::make_shared<Type>();                    \
    }                                                       \
                                                           \
    static const TypeInfo* StaticClass()                    \
    {                                                       \
        static TypeInfo typeInfo(#Type, ParentType::StaticClass()); \
        return &typeInfo;                                   \
    }                                                       \
                                                           \
    virtual const TypeInfo* GetClass() const override       \
    {                                                       \
        return Type::StaticClass();                         \
    }

🎯 객체 생성 함수

std::shared_ptr<CraftObject> SpawnActor(TSubclassOf classType)
{
    if (!classType)
        return nullptr;

    return classType();
}

🧩 사용 예제

TSubclassOf myClass = &Player::CreateInstance;

auto newActor = SpawnActor(myClass);

🔥 이 구조의 의미

이건 단순한 함수 포인터가 아닙니다.

👉 사실상:

“클래스를 값처럼 다루는 것”


🧠 Unreal Engine과의 연결

이 구조는 Unreal Engine의:

  • TSubclassOf
  • SpawnActor
  • UClass

과 매우 유사합니다.


Unreal 스타일 코드

TSubclassOf<AActor> ActorClass;
GetWorld()->SpawnActor(ActorClass);
👉 내부적으로는:
  • 클래스 정보 저장
  • 생성 함수 호출

🎯 왜 이게 중요한가

이 구조는 다음과 같은 곳에서 사용됩니다:

  • 게임 오브젝트 생성
  • 팩토리 패턴
  • 플러그인 시스템
  • 데이터 기반 설계

🔥 장점 정리

1. 런타임 생성 가능

👉 코드 수정 없이 타입 변경


2. 유연한 구조

👉 데이터 기반 설계 가능


3. 엔진 설계 핵심

👉 대부분의 게임 엔진이 사용하는 방식


⚠️ 한계점

  • 생성자 제약 있음 (기본 생성자 필요)
  • 템플릿 기반 확장 필요
  • 타입 안전성 제한

👉 하지만 이후 확장 가능


🧩 확장 방향

다음과 같은 확장이 가능합니다:

  • 생성자 인자 전달
  • 타입 제한 (Base 클래스 기반)
  • 리플렉션 연동
  • 에디터 연결

🎯 시리즈 전체 정리

이번 시리즈를 통해 우리는:

  1. dynamic_cast 이해
  2. 다운캐스팅 위험성
  3. TypeId 기반 RTTI
  4. TypeInfo 기반 RTTI
  5. 타입 기반 객체 생성

👉 즉,

“엔진 수준 타입 시스템”을 직접 구현했습니다


🎮 마무리

이 구조를 이해하면:

  • Unreal Engine 내부 구조
  • Unity의 ScriptableObject 개념
  • 자체 게임 엔진 설계

까지 자연스럽게 연결됩니다.


🔥 마지막 한 줄

👉 RTTI는 단순한 타입 체크가 아니라, 엔진 설계의 시작입니다


🎯 다음 단계

이제 다음으로 확장할 수 있는 주제:

  • Reflection 시스템 구현
  • Property 시스템
  • Serialization
  • ECS 구조

👉 시리즈를 여기까지 따라오셨다면
이미 엔진 구조를 이해할 수 있는 수준에 도달하신 겁니다.

이번 시리즈에서 다룬 RTTI 구조는
실제로 게임 엔진 내부에서 RTTI가 어떻게 사용되는 지를 이해하는 데 중요한 개념입니다.

이와 같은 구조를 처음부터 직접 설계하고 구현해보는 과정은
생각보다 많은 시행착오를 필요로 합니다.

만약 상용 엔진을 사용하는 데에서 한 단계 더 나아가,
엔진의 내부 구조를 직접 만들어보고 싶으시다면
아래 강의도 참고해보셔도 좋습니다.

👉 강의 링크: C++로 만드는 게임 엔진 프레임워크 (소코반과 슈팅 게임으로 배우는 엔진 구조)

직접 구현해보는 경험이 분명 큰 도움이 될 수 있습니다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Please turn AdBlock off

Notice for AdBlock users

Please turn AdBlock off