shared_ptr — std::shared_ptr

shared_ptr — std::shared_ptr

std::shared_ptr는 **공유 소유권(shared ownership)**을 가진 스마트 포인터예요. 여러 포인터가 같은 객체를 공유하고, 마지막 소유자가 파괴될 때 객체가 해제돼요.

객체를 여러 곳에서 공유하되 수명을 자동으로 관리하고 싶을 때 사용해요. 내부적으로 참조 횟수(reference count)를 관리해서, 마지막 참조가 사라지면 객체를 delete해요.

출처: cppreference

본문

std::shared_ptr는 공유 소유권 기반 스마트 포인터예요.

template<class T> class shared_ptr;

같은 객체를 가리키는 여러 shared_ptr가 존재할 수 있고, 각각은 참조 횟수를 공유해요. 참조 횟수가 0이 되면(마지막 소유자가 파괴되면) 가리키던 객체가 삭제돼요.

기본 사용

auto sp = std::make_shared<int>(42);    // 권장: 안전하고 효율적
std::shared_ptr<int> sp2 = sp;          // 공유 (참조 횟수 증가)
std::cout << sp.use_count();            // 2
```                                         // sp, sp2 소멸 시 객체 해제

### 특징

- **공유 소유권** — 여러 포인터가 같은 객체 공유
- **참조 횟수 관리** — `use_count()`, `unique()`
- **약한 참조** — `std::weak_ptr`로 순환 참조 방지
- **커스텀 삭제자** — 소멸 방식 지정

### 생성

`std::make_shared<T>(args...)`를 권장해요. 객체와 제어 블록(참조 횟수)을 한 번에 할당해 효율적이고 예외 안전해요.

```cpp
auto sp = std::make_shared<std::string>("hello");

weak_ptr

순환 참조(두 객체가 서로를 shared_ptr로 참조)를 방지하기 위해 weak_ptr을 써요. weak_ptr는 소유권 없이 관찰만 해요.

std::shared_ptr<int> sp = std::make_shared<int>(5);
std::weak_ptr<int> wp = sp;     // 관찰만 (소유권 없음)
if (auto locked = wp.lock())    // 유효하면 임시 shared_ptr
    std::cout << *locked;

enable_shared_from_this

this로부터 shared_ptr를 얻으려면 std::enable_shared_from_this에서 상속받아 shared_from_this()를 써요.

삭제자와 배열

  • 커스텀 삭제자로 파일·리소스 해제 방식을 지정할 수 있어요.
  • 배열은 std::shared_ptr<T[]>delete[]를 처리해요 (C++17; std::shared_ptr<int[]> 지원).

예외 안전성

객체 생성과 제어 블록 할당을 한 번에 하는 make_shared는 예외가 발생해도 누수가 없어요.

노트 (Notes)

  • 참조 횟수 갱신은 원자적이라 스레드 안전하지만, 객체 접근 자체는 스레드 안전하지 않아요.
  • 순환 참조를 주의해야 해요 (weak_ptr로 해결).
  • 마지막 소유자가 삭제자 호출을 담당해요.

더 알아보기 (Learn more)

cppreference