Class Default Object (CDO)

  • 언리얼 오브젝트의 기본 세팅 상태를 지정
    • 기본 탬플릿 오브젝트
    • Master copy
  • UClass, 리플렉션 시스템에서 작동하기 위해 고안된 클래스에서 이 정보를 포함한다
    • C++ 언어 차원에서 제공하지 않는 리플렉션 기능을 위 방법을 통해 지원
  • 클래스 생성자에 의해 생성된 이후 변경되지 않는다 (Read Only)
  • FObjectInitializer는 생성자 호출 후 처리해야할 정보를 가지고 있다
  • 자식 클래스는 부모 CDO의 값을 상속받아 자신의 CDO를 생성한다
    • 오버라이드된 값은 자식 CDO에 저장한다

CDO 생명 주기 및 인스턴스 생성

  • 엔진이 각 오브젝트에 대한 UClass 객체를 생성하는 시점, 즉 엔진 초기화 시점에 CDO도 생성된다
    • 생성자 부분에 게임플레이와 관련된 코드를 작성하면 안되는 이유
    • 게임 스테이지 정보가 로드되지도 않은 상태에서 호출되기 때문
  • CDO는 엔진 종료까지 메모리에 상주한다
  • 클래스당 하나씩만 존재한다 (싱글톤 패턴)
// 1. 메모리 할당
// 2. 생성자 호출 (CDO든 일반 인스턴스든 동일)
// 3. CDO가 아닌 경우: CDO 값을 복사
// 4. PostInitializeComponents 등 추가 초기화
  • UObject가 생성될 때마다 생성자 코드는 실행된다
    • 다만 각 생성된 객체의 초기화된 값은 CDO에 정의된 값을 따른다
  • Object가 메모리에 할당되는 즉시 생성자가 호출되며, C++ 컴파일러의 룰에 의해 엔진이 이 과정에서 관여할 수 있는 것은 없다
    • 생성된 Object는 UObject와 Actor 초기화가 필요한 경우에 대비한 추가적인 세팅 코드를 가지고 있으며 이는 생성자 호출 이후에 실행된다

Note

  • CDO는 Default 상태를 가지고 있으며, UClass가 CDO를 참조하고 있으며, 새 인스턴스 생성 시 CDO의 값들이 복사된다
  • engine 시작 시의 CDO 생성은 class의 생성자를 호출하게 되므로, 생성자에서의 잘못된 작업은 crash를 야기할 수 있다
  • engine 초기화 중 비교적 앞 단계에서 생성자가 호출되기 때문에, gameplay 관련 코드는 여기에서 실행하지 않는 것을 강하게 권장한다

CDO 접근 방법

// CDO에 접근하는 코드 예시
AMyActor* CDO = AMyActor::StaticClass()->GetDefaultObject<AMyActor>();

CDO를 왜 사용하는가?

  • 프로토타입 패턴의 일환으로 생각하면 될 것 같다
    • UPROPERTY로 마킹된 변수는 에디터에서 기본값을 변경할 수 있으며, 인스턴스별 Override 값을 저장할 수 있다
    • 기본값 변경은 프로토타입을 만든다는 점에서, 상기한 Read Only와는 충돌하지 않는다고 본다
    • 변수 한 두개가 다르고 나머지가 완전히 동일한 인스턴스를 만드는 데 비용을 줄일 수 있다
  • 기본 값 표기 및 기본 값으로 되돌리기 기능을 위해서도 쓰인다
  • 게임 저장 및 로드 시, CDO와 값이 다른 프로퍼티에 대해서만 시행한다
  • GC시 객체 참조를 추적하고 관리하는 데 필요한 정보를 제공한다
    • 그게 뭔지는 몰…?루

출처

Categories: ,

Updated: