KoreanFoodie's Study

언리얼 GetClass 와 StaticClass 의 차이 본문

Game Dev/Unreal C++ : Study

언리얼 GetClass 와 StaticClass 의 차이

GoldGiver 2022. 3. 30. 12:35

GetClass vs StaticClass

코드를 짜다보면, 특정 객체의 클래스 정보를 알기 위해 GetClass 혹은 StaticClass 를 쓰는 것을 볼 수 있다. 그런데 이 둘의 차이는 무엇일까?

 

한 줄 요악 : StaticClass 는 컴파일 타임에서 생성된 UClass 타입의 정보를 얻어오는 것이며, GetClass 는 런타임에서 실제 객체의 클래스를 조회할때 사용된다.

AMyActor* ActorPtr = NewObject<AMyActor>(...);
UObject*  ObjPtr   = Actor;

UClass* MyActorClass  = AMyActor::StaticClass(); // AMyActor
UClass* ObjectClass   = UObject::StaticClass();  // UObject
UClass* ActorPtrClass = ActorPtr->GetClass();    // AMyActor
UClass* ObjPtrClass   = ObjPtr->GetClass();      // AMyActor

StaticClass 에서 조회하는 UClass 에대한 정보는 컴파일 타임에 이미 정해진 것이다. 간단히 얘기하자면, UClass 는 언리얼의 리플렉션 시스템에서 필요로하는 것으로, 타입에 대한 메타데이터라고 보면 된다.

하지만 포인터가 가리키는 실제 객체의 타입은 런타임에서 달라질 수 있으므로, 실제 객체의 클래스를 리턴하는 GetClass 의 리턴값은 StaticClass 의 리턴값과 다를 수 있다.

 

그렇다면 UClass 타입의 정보는 무엇이고 실제 객체의 정보는 무엇일까? 이를 이해하기 위해서는, UClass 타입과 CDO를 공부해야 한다. 관련 글은 이 곳에 정리해 놓았다.

(디테일한 내용은 이득우님 블로그를 참조함)

 

+ 추가 테스트 코드

void ASampleCodingPractise::GetClassVsStaticClass()
{
	UTestUObject* TestUObject = NewObject<UTestUObject>(this,TEXT("TestUObject"));
	UClass* TestUObjectClass = TestUObject->GetClass();
	UClass* TestUObjectStaticClass = UTestUObject::StaticClass();
	UClass* TestUObjectStaticClassTakenFromGetClass = TestUObject->GetClass()->StaticClass();
	UE_LOG(LogCodePractise, Log, TEXT("TestUObject->GetClass(): %s"), *TestUObject->GetClass()->GetName());
	UE_LOG(LogCodePractise, Log, TEXT("UTestUObject::StaticClass(): %s"), *UTestUObject::StaticClass()->GetName());
	UE_LOG(LogCodePractise, Log, TEXT("TestUObject->GetClass()->StaticClass(): %s"), *TestUObject->GetClass()->StaticClass()->GetName());


	bool Test1 = false;
	if (TestUObject->IsA(TestUObject->GetClass()))
	{
		Test1 = true;
	}
	UE_LOG(LogCodePractise, Log, TEXT("TestUObject->IsA(TestUObject->GetClass() result is: %s"), Test1?TEXT("True") : TEXT("False"));


	bool Test2 = false;
	if (TestUObject->IsA(UTestUObject::StaticClass()))
	{
		Test2 = true;
	}
	UE_LOG(LogCodePractise, Log, TEXT("TestUObject->IsA(UTestUObject::StaticClass()) result is: %s"), Test2 ? TEXT("True") : TEXT("False"));

	bool Test3 = false;
	if (TestUObject->IsA(TestUObject->GetClass()->StaticClass()))
	{
		Test3 = true;
	}
	UE_LOG(LogCodePractise, Log, TEXT("TestUObject->GetClass()->StaticClass()) result is: %s"), Test3 ? TEXT("True") : TEXT("False"));

}

 

결과 :

Output:
LogCodePractise: TestUObject->GetClass(): TestUObject
LogCodePractise: UTestUObject::StaticClass(): TestUObject
LogCodePractise: TestUObject->GetClass()->StaticClass(): Class

LogCodePractise: TestUObject->IsA(TestUObject->GetClass() result is: True
LogCodePractise: TestUObject->IsA(UTestUObject::StaticClass()) result is: True
LogCodePractise: TestUObject->GetClass()->StaticClass()) result is: False
Comments