언리얼 C++ 프로그래밍

[언리얼 C++] 스마트 포인터 라이브러리 (1)

언린이 2021. 7. 19. 23:58

언리얼 스마트 포인터 라이브러리는 메모리 할당과 추적의 부담을 해소해주도록 설계된 C++11 스마트 포인터들의 커스텀 구현입니다. 이 구현에는 업계 표준인 쉐어드 포인터, 위크 포인터 그리고 유니크 포인터가 포함되어 있습니다. 또한 null이 불가능한 쉐어드 포인터와 같은 역할을 하는 쉐어드 레퍼런스도 추가되었습니다. 단, 언리얼 오브젝트는 게임 코드에 더 최적화된 별도의 메모리 추적 시스템을 사용하기 때문에 이러한 클래스들은 UObject 시스템과 사용할 수 없습니다.

 

 

1. 스마트 포인터 타입

스마트 포인터 타입 설명
Shared Pointers(TSharedPtr) 쉐어드 포인터는 참조하는 오브젝트를 소유하며, 무기한으로 오브젝트의 소멸을 방지하고, 참조하는 쉐어드 포인터 또는 쉐어드 레퍼런스가 없을 경우에는 궁극적으로 오브젝트를 소멸시킵니다. 쉐어드 포인터는 어느 오브젝트도 참조하지 않는 빈 상태일 수 있습니다. 한편, 모든 null이 불가능한 쉐어드 포인터는 참조하는 오브젝트에 쉐어드 레퍼런스를 생성할 수 있습니다.
Shared References(TSharedRef) 쉐어드 레퍼런스는 참조하는 오브젝트를 소유한다는 측면에서 쉐어드 포인터와 같은 역할을 합니다. 단, null 오브젝트 관련해서는 차이점이 있습니다. 쉐어드 레퍼런스는 항상 null이 불가능한 오브젝트를 참조해야 합니다. 반면에 쉐어드 포인터는 그런 제약이 없기 때문에 쉐어드 레퍼런스는 언제나 쉐어드 포인터로 변환될 수 있으며, 변환된 쉐어드 포인터는 유효한 오브젝트를 참조한다는 점이 보장됩니다. 참조한 오브젝트가 null이 불가능한 오브젝트라는 것을 보장하길 원하거나 공유된 오브젝트 소유권을 보여주길 원할 경우에는 쉐어드 레퍼런스를 사용하세요.
Weak Pointers(TWeakPtr) 위크 포인터는 쉐어드 포인터와 비슷하지만 참조하는 오브젝트를 소유하지 않기 때문에 생명 주기에 영향을 주지 않습니다. 이러한 속성은 참조 주기에 영향을 주지 않기 때문에 매우 유용할 수 있지만, 다시 말해 위크 포인터는 언제든지 사전 경고없이 null이 될 수 있다는 뜻이기도 합니다. 따라서, 위크 포인터는 참조하는 오브젝트에 쉐어드 포인터를 생성할 수 있고, 프로그래머들에게 일시적으로 오브젝트에 대한 안전한 접근을 보장합니다.
Unique Pointers(TUniquePtr) 유니크 포인터는 참조하는 오브젝트를 유일하고 명시적으로 소유합니다. 특정 자원에 대해서는 하나의 유니크 포인터만 있을 수 있기 때문에, 유니크 포인터는 소유권을 이전할 수 있지만 공유는 할 수 없습니다. 유니크 포인터를 복사하려 하면 컴파일 오류가 발생합니다. 또한, 유니크 포인터가 스코프를 벗어나게 되면 참조하는 오브젝트가 자동 소멸됩니다.

위 표는 스마트 포인터의 각 타입들에 대한 설명입니다. 위 표를 참고하여 각 스마트 포인터 타입들을 적합한 경우에 사용하시기 바랍니다.

각 스마트 포인터 타입들은 참조하는 오브젝트의 생명 주기에 영향을 줄 수 있으며, 스마트 포인터 타입마다 오브젝트에 주는 제한사항과 효과도 달라지기 때문에 적절하게 사용해야 합니다.

 

그리고 유니크 포인터가 참조하는 오브젝트에 쉐어드 포인터 또는 쉐어드 레퍼런스를 생성하면 위험할 수 있습니다. 왜냐하면 유니크 포인터가 소멸되면 해당 오브젝트도 함께 소멸되기 때문입니다. 마찬가지로, 쉐어드 포인터 또는 쉐어드 레퍼런스가 참조하는 오브젝트에 유니크 포인터를 생성하지 않는 것이 좋습니다.

 

 

2. 스마트 포인터의 이점

이점 설명
메모리 누수 방지 스마트 포인터들은(위크 포인터 제외) 더 이상 공유된 레퍼런스가 없으면 오브젝트가 자동 소멸됩니다.
위크 레퍼런싱 위크 포인터는 참조 주기에 영향을 주지 않고, 삭제된 오브젝트를 참조하는 포인터를 방지합니다.
선택적인 스레드 안전 언리얼 스마트 포인터 라이브러리에는 멀티스레드에 걸쳐 참조 카운팅을 관리하는 코드인 스레드 세이프 코드가 포함되어 있습니다. 스레드 안전성이 필요하지 않다면 그 대신에 향상된 퍼포먼스를 구현할 수 있습니다.
런타임 안전성 쉐어드 레퍼런스는 절대 null일 수 없으며 언제든지 참조 해제될 수 있습니다.
명확한 의도 관찰자 중에서 오브젝트의 소유자를 쉽게 분별할 수 있습니다.
메모리 스마트 포인터는 64 비트의 C++포인터 크기의 두배입니다. 단, 예외로 유니크 포인터만 C++포인터의 크기와 같습니다.

 

지금까지 언리얼 스마트 포인터 라이브러리에 대해 간단히 알아보았고, 스마트 포인터를 사용하는 것의 이점 또한 알아보았습니다. 스마트 포인터는 메모리 관리 이외에도 여러가지 이점들을 제공해주기 때문에 많이 사용되고 있습니다.

다음 글에서는 스마트 포인터 라이브러리의 사용법에 대해 알아보도록 하겠습니다.