메모리 접근 : 포인터는 메모리 주소를 저장한다. 프로그램은 해당 메모리 위치에 직접 접근할 수 있게 된다.
간접 참조 : 포인터를 사용하면 변수의 값을 직접 참조하는 대신, 변수의 메모리 주소를 통해 간접적으로 참조할 수 있다. 데이터를 유연하게 관리할 수 있게 해준다.
동적 메모리 관리 : 동적 메모리 할당과 관리에 있어서 필수적이다. 프로그램 실행 중에 메모리의 크기를 변경하거나, 필요에 따라 메모리를 할당하고 해제하는 것이 가능해진다.
void UMover::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
AActor* Owner = GetOwner();
FString Name = Owner -> GetActorNameOrLabel();
FVector OwnerLocation = Owner -> GetActorLocation();
FString OwnerLocationString = OwnerLocation.ToCompactString();
UE_LOG(LogTemp, Display, TEXT("Mover Owner : %s with location %s"), *Name, *OwnerLocationString);
}
AActor* Owner
와 같이 포인터를 사용하여 AActor
객체의 주소를 저장하고 있다. 여기서 AActor
는 UE에서 모든 액터의 베이스 클래스다. 게임 오브젝트를 나타낸다.
Actor* Owner
UMover
컴포넌트를 소유하는 액터의 메모리 주소를 저장한다. UMover
컴포넌트는 소유자 액터의 위치(GetActorLocation()
)이나 이름(GetActorNameOrLabel()
)와 같은 속성에 접근할 수 있게 된다.
FActorComponentTickFunction* ThisTickFucntion
이 포인터는 틱 함수의 메타데이터를 포함하고 있으며, 틱이 호출될 떄 마다 엔전에 의해 전달된다.
(지극히 개인적인 의견입니다.)
포인터를 사용하는 것은 책장에서 책을 찾는 것이라 생각하자. 책장에 있는 각 책에는 고유한 위치가 있는데, 책의 제목을 알고 있으면 그 책을 찾아볼 수 있지만, 책의 위치(포인터)를 알고 있다면 더 빠르게 찾아갈 수 있다. 게임 개발에서는 게임 월드에 있는 매우 매우 많은 객체들에 대해 접근해야한다. 이때 객체의 주소를 알고 있으면, 그 객체에 빠르게 접근해 필요한 작업을 할 수 있다.
예를 들어, 어떤 객체의 바이너리 데이터가 010101010110101010101010이라고 할 때, 이 데이터를 직접 여러 함수나 객체에 전달하려면, 해당 데이터의 복사본이 메모리상에 여러번 할당된다. 만약 데이터가 매우 매우 매우 크다면, 프로그램의 메모리 사용량이 증가한다.
-> 그러나 포인터를 사용하면, 바이너리 데이터의 메모리 주소만을 가리키는 포인터(ex : 010101)를 사용해 데이터를 전달한다. 포인터는 원본 데이터의 위치를 가르키기 때문에, 데이터 자체의 크기와 관계없이 포인터의 크기는 일정하다. 이렇게 데이터를 관리하면, 원본 데이털르 직접 복사하고 전달하는 것 보다 훨씬 적은 메모리를 사용하면서도 필요한 작업을 수행할 수 있다.