memory_shared_ptr
memory_shared_ptr (std::shared_ptr)
<memory> 헤더에 정의되어 있어요. 포인터를 통해 객체의 공유 소유권을 유지하는 스마트 포인터예요. 여러 shared_ptr 객체가 같은 객체를 소유할 수 있어요. 객체는 소유한 shared_ptr이 마지막으로 파괴되거나, operator=·reset()으로 다른 포인터를 대입할 때 파괴되고 메모리가 해제돼요. C++11부터 도입됐어요.
출처: cppreference
본문
template< class T > class shared_ptr;
(C++11부터)
std::shared_ptr은 포인터를 통해 객체의 공유 소유권을 유지하는 스마트 포인터예요. 여러 shared_ptr 객체가 같은 객체를 소유할 수 있어요. 다음 중 하나가 일어날 때 객체가 파괴되고 그 메모리가 해제돼요.
- 객체를 소유하는 마지막
shared_ptr이 파괴될 때. - 객체를 소유하는 마지막
shared_ptr이operator=나reset()으로 다른 포인터를 대입받을 때.
객체는 delete-표현식 또는 구성 시 shared_ptr에 제공된 커스텀 삭제자를 사용해 파괴돼요.
shared_ptr은 한 객체의 소유권을 공유하면서 다른 객체를 가리키는 포인터를 저장할 수 있어요. 이 기능은 어떤 객체를 소유하면서 그 객체에 속한 멤버 객체를 가리키는 데 쓸 수 있어요. 저장된 포인터는 get()·역참조·비교 연산자가 접근하는 것이고, 관리되는 포인터는 use count가 0이 될 때 삭제자에 전달되는 것이에요.
shared_ptr은 객체를 소유하지 않을 수도 있는데, 이 경우 empty라고 불러요. 모든 shared_ptr 특수화는 CopyConstructible·CopyAssignable·LessThanComparable을 만족하고 bool로 문맥적 변환이 가능해요.
모든 멤버 함수(복사 생성자·복사 대입 포함)는 같은 객체의 소유권을 공유하는 복사본들이더라도 서로 다른 shared_ptr 객체에서 동기화 없이 여러 스레드가 호출할 수 있어요. 같은 shared_ptr 객체를 동기화 없이 접근하고 그 중 하나라도 비-const 멤버 함수를 쓰면 데이터 경쟁이 발생하며, std::atomic<shared_ptr>로 막을 수 있어요.
멤버 타입
element_type:T(C++17까지),std::remove_extent_t<T>(C++17부터)weak_type(C++17):std::weak_ptr<T>
멤버 함수
- (생성자): 새
shared_ptr생성 - (소멸자): 더 이상 연결된
shared_ptr이 없으면 소유한 객체 파괴 operator=:shared_ptr대입reset: 관리 객체 교체swap: 관리 객체 맞바꾸기get: 저장된 포인터 반환operator*/operator->: 저장된 포인터 역참조operator[](C++17): 저장된 배열에 인덱스 접근use_count: 같은 관리 객체를 참조하는shared_ptr수 반환operator bool: 저장된 포인터가 비-널인지owner_before: 소유자 기반 순서 제공owner_hash(C++26),owner_equal(C++26)
비멤버 함수
make_shared/make_shared_for_overwrite, allocate_shared/allocate_shared_for_overwrite, static/dynamic/const/reinterpret_pointer_cast, get_deleter, 비교 연산자, operator<<, std::swap 특수화, 원자 접근 함수 등이 있어요.
주의 (Notes)
- 객체의 소유권은 그 값을 다른
shared_ptr에 복사 생성·복사 대입하는 경우에만 공유할 수 있어요. 다른shared_ptr이 소유한 원시 포인터로 새shared_ptr을 만들면 미정의 동작이에요. T는 불완전 타입일 수 있어요. 단 원시 포인터 생성자와reset(Y*)는 완전 타입에 대한 포인터로만 호출할 수 있어요.T는 함수 타입일 수도 있어요. 이 경우 함수 포인터를 관리하며, 동적 라이브러리·플러그인이 함수 중 하나라도 참조되는 동안 로드된 상태를 유지하는 데 쓰이기도 해요.
구현 참고 (Implementation notes)
일반적 구현에서 shared_ptr은 두 포인터만 보유해요. 저장된 포인터(get()이 반환)와 제어 블록에 대한 포인터요. 제어 블록은 관리 객체에 대한 포인터 또는 관리 객체 자체, 타입 지움된 삭제자, 타입 지움된 할당자, 객체를 소유하는 shared_ptr 수, 객체를 참조하는 weak_ptr 수를 보유하는 동적 할당 객체예요.