프로그래밍에서 클래스끼리 부모-자식 관계가 있을 때,
참조나 포인터를 어떻게 변환해서 사용하는지에 따라 두 가지 캐스팅이 등장한다.
자식 → 부모로 변환하는 것.
항상 안전하고, 자동으로 변환된다.
자식 클래스는 부모 클래스의 기능을 모두 포함하고 있기 때문에
부모 포인터로 바라봐도 문제가 생기지 않는다.
class A {};
class B : public A {};
B* Child = new B();
A* Parent = Child; // 업캐스팅 (자동)
AMyCharacter* MyChar = GetWorld()->SpawnActor<AMyCharacter>();
AActor* ActorPtr = MyChar; // 업캐스팅
부모 → 자식으로 변환하는 것.
항상 위험하며, 반드시 체크해야 한다.
부모 포인터가 실제로 자식 객체를 가리키는지 확신할 수 없기 때문.
A* Parent = new B();
B* Child = static_cast<B*>(Parent); // 위험
AActor* ActorPtr = GetSomeActor();
AMyCharacter* MyChar = Cast<AMyCharacter>(ActorPtr);
if (MyChar)
{
// 캐스팅 성공 → ActorPtr이 실제로 AMyCharacter임
}
else
{
// 캐스팅 실패 → 타입이 다름
}
Cast<>는 실패 시 nullptr을 반환하기 때문에
엔진 크래시를 막을 수 있는 가장 안전한 다운캐스팅 방식이다.
업캐스팅은 객체 자체를 바꾸는 것이 아니라
“가리키는 관점만 부모로 바꾸는 것”이기 때문이다.
B Child;
A& Ref = Child; // 참조 업캐스팅
A* Ptr = &Child; // 포인터 업캐스팅
반대로 값으로 바꾸면 업캐스팅이 아니라
복사 + 잘림(slicing)이 발생하므로 쓰지 않는다.
B Child;
A Parent = Child; // 잘림 발생 → 비추천
void OnOverlap(AActor* OtherActor)
{
AMyCharacter* MyChar = Cast<AMyCharacter>(OtherActor);
if (MyChar)
{
UE_LOG(LogTemp, Warning, TEXT("플레이어 진입!"));
}
}
UPrimitiveComponent* Comp = Cast<UPrimitiveComponent>(Hit.GetComponent());
TArray<AActor*> Actors;
for (AActor* Actor : Actors)
{
ADoorBase* Door = Cast<ADoorBase>(Actor);
if (Door)
{
// Door만 골라서 동작
}
}
Cast<>를 꼭 사용nullptr로 안전하게 처리