본문 바로가기

TIL

매크로와 RTTI

#define UCLASS(ClassName, ParentClass) \
public: \
    static UClass* StaticClass() { \
        static UClass StaticClassInstance(#ClassName, ParentClass::StaticClass()); \
        return &StaticClassInstance; \
    } \
    virtual UClass* GetClass() const { return StaticClass(); }

위 매크로를 사용하면.

class A : public SceneComp
{
	UCLASS(A, SceneComp)
public: 
	//기타...
}

아래처럼 코드 확장.

class A : public sceneComp
{
	static UClass* StaticClass() {
        static UClass StaticClassInstance(#ClassName, ParentClass::StaticClass());
        return &StaticClassInstance;
    }
    virtual UClass* GetClass() const { return StaticClass(); }
 public:
 	//기타...
 }

 

StaticClass( ) 함수 호출 순서

1. A::StaticClass( ) 호출

2. 부모 클래스의 StaticClass () 호출

-  A의 StaticClassInstance를 생성하기 위해 생성자 인자중 두 번째 인자는 sceneComp::StaticClass();

- A를 생성하기 전에, A의 부모 클래스인 sceneComp의 StaticClass함수가 호출되어 sceneComp 클래스의 메타데이터 객체 초기화 됨.

 

3. 재귀적 부모 체인 호출.

sceneComp 클래스 또한 UCLASS 매크로를 사용하여 정의되어있으므로 sceneComp 내부에도 StaticClass()함수가 존재.

이 과정은 sceneComp의 부모 클래스이 StaticClass 호출로 이어지고 결국 최상위인 UClass의 StaticClass에 도달.

 

UClass의 StaticClass()

class UClass {
public:
    static UClass* StaticClass() {
        static UClass RootClass("UClass", nullptr);
        return &RootClass;
    }
    // 기타 멤버들...
};

최종적으로 UClass::StaticClass()는 "UClass"라는 이름의 루트 메타데이터 주소 반환.

 

4. A클래스의 정적 변수 초기화 완료

부모 체인에서 모든 StaticClass( ) 호출이 완료되면, A::StaticClas()의 정적 변수 StaticClassInstance가 "A"라는 이름과 sceneComp의 메타데이터를 인자로 생성됨.

5. A::StaticClass() 반환.

마지막으로, 생성된 StaticClassInstance의 주소가 반환되어 A클래스이 메타데이터로 활용.

 

 

 

IsA

 

//UObject.h
template<typename T>
bool IsA()
{
	return GetClass()->IsA<T>();
}

 

// UClass.h
bool IsChildOf(const UClass* ParentClass) const
{
	const UClass* Class = this;
	while (Class)
	{
		if (Class == ParentClass)
		{
			return true;
		}
		Class = Class->SuperClass;
	}
	return false;
}

template<typename T>
bool IsA() const
{
	return IsChildOf(T::StaticClass());
}

UObject 쪽의 IsA() 함수는 현재 객체의 GetClass()를 호출하여 그 객체의 UClass(메타데이터)를 얻음.

그런 다음 이 UClass 객체의 IsA<T>()를 호출.

UClass의 IsA<T>() 함수는 템플릿 인자로 받은 T 클래스의 StaticClass()를 이용해,

현재 클래스의 상속 체인 내에 T 클래스의 메타데이터가 있는지를 IsChildOf() 함수를 통해 확인.

'TIL' 카테고리의 다른 글

UE Actor 라이프사이클  (0) 2025.03.21
World Grid 렌더링 최적화: 두 가지 접근 방식  (0) 2025.03.18
std::vector erase, std::remove 관련  (0) 2025.03.18
FName  (0) 2025.03.18
Today I Learned  (0) 2025.02.24