[Unreal Engine] 스마트 포인터 (C++ vs UE)

2024. 10. 29. 13:28·Game Programming/Unreal Engine
728x90
반응형

개요

이번 포스팅에서는 기본적인 C++의 스마트 포인터와 언리얼 엔진에서의 스마트 포인터에 대해 정리해보도록 하겠습니다.


C++ 스마트 포인터 (Unique, Shared, Weak)

스마트 포인터는 메모리 관리를 자동화해 메모리 누수를 방지하고 객체의 수명을 관리하는데 유용합니다.

 

Unique_ptr

  • 단일 소유권을 가지는 스마트 포인터입니다.
  • 소유권이 하나 뿐이므로, 복사가 불가 합니다.
  • 객체가 더 이상 사용되지 않는 경우 소멸되어 자동으로 메모리가 해제됩니다.
#include <iostream>
// 스마트 포인터를 사용하기 위한헤더 
#include <memory>

using namespace std;

class MyClass {
public:
    MyClass() { std::cout << "MyClass 생성\n"; }
    ~MyClass() { std::cout << "MyClass 소멸\n"; }
    void ShowMessage() { std::cout << "Hello, unique_ptr!\n"; }
};

int main() {
    // 스마트 포인터 생성
    unique_ptr<MyClass> ptr = std::make_unique<MyClass>();
    ptr->ShowMessage();
    
    // 소멸자는 main 함수 종료 시 자동 호출됩니다.
    // * 더이상 사용되지않는 시점에 자동 소멸됩니다.
}

 

Shared_ptr

  • 참조 횟수(Reference Count)를 기반으로 다중 소유권을 지원하는 스마트 포인터입니다.
  • 참조하고 있는 마지막 포인터가 소멸할 때 자동으로 메모리가 해제됩니다.
#include <iostream>
#include <memory>

using namespace std;


class MyClass 
{
public:
    MyClass() { std::cout << "MyClass 생성\n"; }
    ~MyClass() { std::cout << "MyClass 소멸\n"; }
    void ShowMessage() { std::cout << "Hello, shared_ptr!\n"; }
};

int main() 
{
    // 스마트 포인터 생성 (참조 횟수 : 1)
    shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    {
        shared_ptr<MyClass> ptr2 = ptr1;  // 참조 횟수 증가 (참조 횟수 : 2)
        ptr2->ShowMessage();
    }  
    // ptr2가 범위를 벗어나 참조 횟수 감소 (참조 횟수 : 1)
    ptr1->ShowMessage();
    
    // main 함수 종료 시 참조 횟수 감소 (참조 횟수 : 0)
    // * 참조 횟수가 0이므로 자동 소멸합니다.
}

 

Weak_ptr

  • 참조 횟수에 영향을 주지 않는 스마트 포인터입니다.
  • shared_ptr과 함께 사용되며, 순환 참조 문제를 해결할 수 있습니다.
  • shared_ptr을 사용해 메모리가 해제되었는지 확인 후 사용 가능합니다. (lock)
#include <iostream>
#include <memory>

using namespace std;

class MyClass 
{
public:
    MyClass() { std::cout << "MyClass 생성\n"; }
    ~MyClass() { std::cout << "MyClass 소멸\n"; }
    void ShowMessage() { std::cout << "Hello, weak_ptr!\n"; }
};

int main() 
{
    // shared_ptr 생성 (참조 횟수 : 1)
    shared_ptr<MyClass> ptr = std::make_shared<MyClass>();
    // weak_ptr 생성 (ptr에 대한 참조 횟수 증가 X)
    weak_ptr<MyClass> weakPtr = ptr;

    if (shared_ptr<MyClass> tempPtr = weakPtr.lock()) 
    {
        tempPtr->ShowMessage();
    } else {
        std::cout << "객체가 이미 소멸되었습니다.\n";
    }
}

 

순환 참조 예시

#include <iostream>
#include <memory>

class B;  // 전방 선언

class A 
{
public:
    std::shared_ptr<B> ptrB;
    
    A() { std::cout << "A created\n"; }
    ~A() { std::cout << "A destroyed\n"; }
};

class B 
{
public:
    std::shared_ptr<A> ptrA;
    
    B() { std::cout << "B created\n"; }
    ~B() { std::cout << "B destroyed\n"; }
};

int main() 
{
    // 스마트 포인터 생성 (a, b : 참조 횟수 : 1)
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    
    // 스마트 포인터 복사 (a, b : 참조 횟수 : 2)
    a->ptrB = b;
    b->ptrA = a;
    
    // a와 b는 범위를 벗어나도 순환 참조로 인해 참조 횟수가 0이 되지 않음
    // * 즉, 순환 참조 발생으로 인해 A와 B가 파괴되지 않음
}

언리얼 스마트 포인터

언리얼 엔진에서 제공하는 스마트 포인터 라이브러리는 메모리 할당과 추적의 부담을 해소해주도록 C++ 11 스마트 포인터들의 커스텀 구현입니다.

 

스마트 포인터들은 갖고 있거나 참조하는 오브젝트의 생명 주기에 영향을 줄 수 있으며, 다른 스마트 포인터마다 오브젝트에 주는 제한사항과 효과도 달라집니다.

 

TUniquePtr

  • C++의 unique_ptr과 유사하게 단일 소유권을 제공합니다.
  • 기존과 동일하게 복사가 불가능하며, 범위(스코프)를 벗어나게 되면 참조하는 오브젝트가 자동 소멸합니다.

TSharedPtr

  • C++의 shared_ptr과 유사하게 참조 횟수를 관리하여 다중 소유권을 지원합니다.
  • 참조하는 TSharedPtr 또는 TSharedRef가 없을 경우 해당 오브젝트를 소멸시킵니다.
  • TSharedPtr은 널 포인터로 초기화할 수 있고, 참조가 끊어진 경우에도 널(null)을 가질 수 있습니다.

TSharedRef

  • TSharedRef는 참조 횟수 기반의 스마트 포인터로 TSharedPtr과 유사합니다.
  • 반드시 유효한 객체를 참조해야 한다는 강제 조건이 존재합니다. (Null pointer 초기화 불가능)
  • 즉, TSharedRef는 널 포인터를 허용하지 않으며, 객체가 항상 유효함을 보장합니다.

TWeakPtr

  • TSharedPtr와 함께 사용되며, 순환 참조를 방지합니다.
  • Pin 함수를 사용하여 실제 TSharedPtr로 변환한 뒤 사용 여부를 확인할 수 있습니다.

TSharedPtr와 TSharedRef의 관계 및 변환

TSharedPtr → TSharedRef 변환

  • TSharedRef는 항상 유효한 객체를 참조해야 하므로 TSharedPtr에서 TSharedRef로 변환할 수 있습니다.
  • 이때 TSharedPtr이 유효해야만 변환이 가능하며, 그렇지 않으면 에러가 발생합니다.

TSharedRef → TSharedPtr 변환

  • TSharedRef에서 TSharedPtr로 변환은 간단합니다.
  • TSharedRef 는 항상 유효하므로 널 체크 없이 TSharedPtr로 변환 가능합니다.
// TSharedPtr -> TSharedRef
TSharedPtr<MyClass> SharedPtr = MakeShared<MyClass>();
TSharedRef<MyClass> SharedRef = SharedPtr.ToSharedRef();

// TSharedRef -> TSharedPtr
TSharedPtr<MyClass> ConvertedPtr = SharedRef;

언리얼 엔진에서 스마트 포인터를 사용하는 이유

언리얼 엔진의 리플렉션 시스템은 객체 관리에 유용하지만 모든 상황에 대응하지는 못합니다.

다음과 같은 경우 스마트 포인터를 활용하는 것이 적합합니다.

  • UObject를 상속받지 않은 클래스의 객체 메모리 관리
  • 특정 객체의 수명을 코드에서 명확히 통제하고자 할 때
  • 순환 참조 문제를 예방하고 메모리 누수를 방지하고자 할 때
  • 레퍼런스 카운팅을 통해 객체를 안전하게 공유할 때

참고 자료

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/smart-pointers-in-unreal-engine

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Game Programming > Unreal Engine' 카테고리의 다른 글

[Unreal Engine] Delegate  (0) 2024.10.30
[Unreal Engine] DataAsset, Lazy Loading  (0) 2024.10.28
[Unreal Engine 5] AI Controller  (0) 2024.10.01
[Unreal Engine 5] FABRIK IK  (0) 2024.08.25
[Unreal Engine] 리플렉션 시스템, CDO  (0) 2024.07.26
'Game Programming/Unreal Engine' 카테고리의 다른 글
  • [Unreal Engine] Delegate
  • [Unreal Engine] DataAsset, Lazy Loading
  • [Unreal Engine 5] AI Controller
  • [Unreal Engine 5] FABRIK IK
리태s
리태s
게임 클라이언트 프로그래머 직무를 준비하며 공부한 내용을 정리한 블로그입니다.
    반응형
    250x250
  • 리태s
    LeeTaes 공부노트
    리태s
  • 전체
    오늘
    어제
    • Home (165)
      • 프로젝트 (20)
        • Isaac 3D (5)
        • TimelessAdventure (13)
        • FruitsPuzzle (2)
      • Game Programming (25)
        • C# (8)
        • Unity Engine (6)
        • Unreal Engine (8)
        • UE_Multiplayer (3)
      • 코딩테스트 (111)
        • 프로그래머스 (Lv. 0) (27)
        • 프로그래머스 (Lv. 1) (31)
        • 프로그래머스 (Lv. 2) (21)
        • 백준 (Study) (29)
        • 알고리즘 (3)
      • CS지식 (7)
        • 운영체제 (7)
      • 일상 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    ai controller
    Unreal Engine
    Algorithm
    pcce 기출문제
    issac3d
    dataasset
    unity
    c#
    2022 kakao
    후기
    project t.a develop
    구현
    프로세스
    C++
    백준
    프로젝트
    2019 kakao
    sesac
    delegate
    fruitspuzzle
    프로그래머스
    CS지식
    timelessadventure
    2018 kakao
    tsoftobjectptr
    unrealengine
    fsoftobjectpath
    청년취업사관학교
    Summer/Winter Coding
    코딩테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
리태s
[Unreal Engine] 스마트 포인터 (C++ vs UE)
상단으로

티스토리툴바