오늘은 언리얼엔진 스마트포인터에 대해서 알아봤습니다.
언리얼 엔진이 제공하는 스마트 포인터에는 TSharedPtr, TWeakPtr, TUniquePtr이 있습니다.
1. TSharedPtr (참조 카운팅 스마트 포인터)란?
- TSharedPtr은 참조 카운트 기반의 스마트 포인터이며 여러 개의 TSharedPtr이 같은 객체를 공유할 수 있습니다.
- TSharedPtr이 소멸될 때 객체가 자동으로 삭제됩니다.
- TSharedPtr은 nullptr이 될 수 있으므로 IsValid()를 이용한 체크가 가능합니다.
예시 코드
#include "CoreMinimal.h"
#include <iostream>
class FMyObject
{
public:
FMyObject() { UE_LOG(LogTemp, Warning, TEXT("FMyObject 생성")); }
~FMyObject() { UE_LOG(LogTemp, Warning, TEXT("FMyObject 삭제")); }
void PrintMessage() { UE_LOG(LogTemp, Warning, TEXT("Hello from FMyObject!")); }
};
void TestSharedPtr()
{
TSharedPtr<FMyObject> Ptr1 = MakeShared<FMyObject>(); // 객체 생성 및 참조 카운트 1 증가
{
TSharedPtr<FMyObject> Ptr2 = Ptr1; // 참조 카운트 2 증가
Ptr2->PrintMessage();
} // Ptr2가 범위를 벗어나면서 참조 카운트 1 감소
UE_LOG(LogTemp, Warning, TEXT("Ptr1 남아 있음"));
} // Ptr1이 범위를 벗어나면서 객체가 자동 삭제됨
2. TWeakPtr (약한 참조, 순환 참조 방지)란?
- TSharedPtr을 직접 보유하지 않고, 약한 참조를 제공합니다.
- 참조 카운트를 증가시키지 않아 순환 참조 문제를 방지합니다.
- 객체가 삭제됐는지 확인하려면 .Pin()을 사용해야 합니다.
- TWeakPtr은 객체를 직접 사용하지 못하며, Pin()을 사용해 TSharedPtr 로 변환한 후 사용해야 합니다.
예시 코드
class FParent;
class FChild;
class FParent
{
public:
TSharedPtr<FChild> Child;
~FParent() { UE_LOG(LogTemp, Warning, TEXT("FParent 삭제")); }
};
class FChild
{
public:
TWeakPtr<FParent> Parent; // TWeakPtr 사용하여 순환 참조 방지
~FChild() { UE_LOG(LogTemp, Warning, TEXT("FChild 삭제")); }
};
void TestWeakPtr()
{
TSharedPtr<FParent> Parent = MakeShared<FParent>();
TSharedPtr<FChild> Child = MakeShared<FChild>();
Parent->Child = Child;
Child->Parent = Parent; // TWeakPtr 사용 순환 참조 문제 회피
UE_LOG(LogTemp, Warning, TEXT("TestWeakPtr 종료"));
} // Parent, Child가 범위를 벗어나면서 정상적으로 삭제됨
TWeakPtr<FMyObject> WeakPtr = MySharedPtr;
if (TSharedPtr<FMyObject> ValidPtr = WeakPtr.Pin())
{
ValidPtr->PrintMessage(); // 객체가 살아있다면 실행
}
else
{
UE_LOG(LogTemp, Warning, TEXT("객체가 삭제됨"));
}
3. TUniquePtr (단일 소유권 스마트 포인터)란?
- 하나의 포인터만 객체를 소유할 수 있습니다.
- 다른 TUniquePtr로 복사할 수 없습니다.
- MoveTmep()를 사용하여 이동 연산이 가능합니다.
- 객체가 필요 없어지면 자동으로 삭제됩니다.
예시 코드
void TestUniquePtr()
{
TUniquePtr<FMyObject> UniquePtr = MakeUnique<FMyObject>();
UniquePtr->PrintMessage(); // 객체 사용
UniquePtr.Reset(); // 명시적으로 삭제 가능
if (!UniquePtr)
{
UE_LOG(LogTemp, Warning, TEXT("UniquePtr가 삭제됨"));
}
}
void MoveUniquePtr(TUniquePtr<FMyObject> NewOwner)
{
if (NewOwner)
{
NewOwner->PrintMessage();
}
}
void TestMoveUniquePtr()
{
TUniquePtr<FMyObject> UniquePtr = MakeUnique<FMyObject>();
MoveUniquePtr(MoveTemp(UniquePtr)); // UniquePtr의 소유권을 이동
if (!UniquePtr)
{
UE_LOG(LogTemp, Warning, TEXT("UniquePtr가 이동됨"));
}
}'언리얼 엔진' 카테고리의 다른 글
| 캐릭터 에셋에 붙은 무기 제거하기 (0) | 2025.02.19 |
|---|---|
| 언리얼 TSublcassOf<>와 TSoftclassPtr<> (0) | 2025.02.07 |
| 언리얼 Enhanced Input System (0) | 2025.02.05 |
| 부모 액터를 중심으로 회전 하는 자식 액터 만들기 (0) | 2025.01.31 |
| 언리얼 VInterpTo 활용하여 왕복 운동 하는 엑터 만들기 (0) | 2025.01.24 |