-
C++
에서는 일반적인 생 포인터 (raw pointer
,T*
) 사용이 위험할 수 있습니다.- 생 포인터(
raw pointer
)을 잘 모르시면 다음글을 참조하세요. https://j2doll.tistory.com/1268
- 생 포인터(
-
소유권을 명확하게 표현하지 않으면 메모리 해제 문제, 죽은 포인터(
Dangling Pointer
) 접근, 이중 해제(Double Delete
) 등의 심각한 버그를 유발할 수 있기 때문입니다.
-
이러한 문제를 해결하기 위해
std::unique_ptr
과std::shared_ptr
같은 스마트 포인터가 도입되었지만, 경우에 따라 객체의 소유권을 가지지 않고 단순히 관찰만 하는 포인터가 필요할 때가 있습니다. -
예를 들어, 다음과 같은 경우입니다:
- 특정 객체를 직접 할당/해제하지 않으면서 단순 참조할 때
unique_ptr
이나shared_ptr
의 내부 객체를 소유권 없이 읽기 또는 임시 접근할 때- 포인터가 소유권을 가지지 않는다는 의미를 코드에 명확히 드러내고 싶을 때
-
이러한 필요를 해결하기 위해
C++23
에서는 **std::observer_ptr
**이 도입되었습니다. -
이제
T*
대신std::observer_ptr<T>
를 사용하면 더 명확하고 안전한 코드를 작성할 수 있습니다.
std::observer_ptr<T>
는 소유권을 가지지 않고 객체를 참조하는 포인터입니다.- 쉽게 말해 **"T*를 감싸면서 의미를 명확하게 만드는 래퍼"**입니다.
- 소유권 없음 →
std::unique_ptr
과 달리 객체를 해제하지 않음 nullptr
상태 허용 → NULL 포인터로 초기화 가능- 안전한 인터페이스 →
T*
대신 사용하면 코드 가독성이 향상됨 - 포인터 연산 지원 →
->
,*
연산을 통해 원본 객체 접근 가능
-
cpp
namespace std { template <class T> class observer_ptr { public: // 생성자 constexpr observer_ptr() noexcept; constexpr observer_ptr(nullptr_t) noexcept; constexpr explicit observer_ptr(T* p) noexcept; // 포인터 관리 constexpr void reset(T* p = nullptr) noexcept; constexpr T* release() noexcept; // 접근 constexpr T* get() const noexcept; constexpr T& operator*() const; constexpr T* operator->() const noexcept; // bool 변환 constexpr explicit operator bool() const noexcept; }; }
-
cpp
#include <iostream> #include <memory> #include <observer_ptr> // C++23부터 <memory>에 포함됨 (일부 구현에서는 <observer_ptr> 헤더 별도 필요) struct Foo { void hello() { std::cout << "Hello from Foo\n"; } }; int main() { Foo f; std::observer_ptr<Foo> optr(&f); // 소유권 없이 f를 참조 if (optr) { optr->hello(); // observer_ptr을 통해 Foo의 멤버 함수 호출 } optr.reset(); // nullptr로 설정 }
-
std::observer_ptr<T>
는 스마트 포인터(unique_ptr
,shared_ptr
)의 대체재가 아닙니다. -
대신, 소유권이 필요하지 않은 경우에만 생 포인터(
T*
) 대신 사용하여 코드의 의미를 더욱 명확하게 만들 수 있습니다.
- ✅ 객체의 소유권을 가지지 않고 참조만 할 때
- ✅ 스마트 포인터 내부 객체를 읽거나 접근할 때
- ✅ 코드에서 "나는 이 객체를 소유하지 않는다"는 의미를 강조할 때
- 🚫 동적 할당된 객체를 직접 관리할 때 →
unique_ptr
이나shared_ptr
사용 - 🚫 객체 수명이
observer_ptr
보다 짧을 가능성이 있을 때 → Dangling Pointer 방지 필요
-
C++23
의std::observer_ptr
은 생 포인터(raw pointer
)보다 안전하고 의미가 명확한 대안 입니다. -
소유권이 필요 없는 경우
std::observer_ptr<T>
를 사용하면 더 안전하고 유지보수하기 쉬운 코드를 작성할 수 있습니다. -
따라서, 생 포인터를 사용해야 하는 경우라면
std::observer_ptr
을 고려해 보는 것이 좋습니다. 🚀
- 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄
'C C++' 카테고리의 다른 글
std::enable_shared_from_this — 객체 내부에서 안전하게 shared_ptr을 생성하는 방법 (0) | 2025.03.20 |
---|---|
Modern C++에서 unique_ptr 반환 시 암시적 이동(Implicit Move)과 RVO(Return Value Optimization) 이해 (0) | 2025.03.20 |
생 포인터(raw pointer) std::raw_pointer — 표준 C++에 존재할까? (0) | 2025.03.20 |
C++ 스마트 포인터(std::unique_ptr, std::shared_ptr, std::weak_ptr) 명시적 해제(reset()) (0) | 2025.03.20 |
C++17에서 std::auto_ptr가 제거된 이유 (0) | 2025.03.20 |