💡 퀵 접속: cpp.kr/shared_ptr

shared_ptr

C++ 표준 라이브러리의 스마트 포인터로, 여러 shared_ptr이 동일한 객체를 공유할 수 있습니다. 참조 카운팅을 통해 마지막 shared_ptr이 소멸될 때 객체를 자동으로 해제합니다.

기본 사용법

#include <iostream>
#include <memory>

int main() {
    // 동적 할당
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    
    // 다른 shared_ptr이 같은 객체를 가리키도록 함
    std::shared_ptr<int> ptr2 = ptr1;
    
    // 참조 카운트 확인
    std::cout << "참조 카운트: " << ptr1.use_count() << std::endl;
    
    // 값 접근
    std::cout << "ptr1의 값: " << *ptr1 << std::endl;
    std::cout << "ptr2의 값: " << *ptr2 << std::endl;
    
    return 0;
}

실행 결과:

참조 카운트: 2
ptr1의 값: 42
ptr2의 값: 42

객체 공유

#include <iostream>
#include <memory>
#include <vector>

class Resource {
public:
    Resource() { std::cout << "리소스 생성" << std::endl; }
    ~Resource() { std::cout << "리소스 해제" << std::endl; }
    void use() { std::cout << "리소스 사용 중" << std::endl; }
};

int main() {
    // 리소스 생성
    std::shared_ptr<Resource> res = std::make_shared<Resource>();
    
    // 여러 곳에서 리소스 공유
    std::vector<std::shared_ptr<Resource>> users;
    users.push_back(res);
    users.push_back(res);
    
    // 각 사용자가 리소스 사용
    for (const auto& user : users) {
        user->use();
    }
    
    // 참조 카운트 확인
    std::cout << "참조 카운트: " << res.use_count() << std::endl;
    
    return 0;
}

실행 결과:

리소스 생성
리소스 사용 중
리소스 사용 중
참조 카운트: 3
리소스 해제

약한 참조

#include <iostream>
#include <memory>

int main() {
    // shared_ptr 생성
    std::shared_ptr<int> shared = std::make_shared<int>(100);
    
    // weak_ptr 생성 (참조 카운트를 증가시키지 않음)
    std::weak_ptr<int> weak = shared;
    
    // shared_ptr이 유효한지 확인
    if (auto locked = weak.lock()) {
        std::cout << "값: " << *locked << std::endl;
    }
    
    // shared_ptr 해제
    shared.reset();
    
    // weak_ptr이 만료되었는지 확인
    if (weak.expired()) {
        std::cout << "weak_ptr이 만료되었습니다." << std::endl;
    }
    
    return 0;
}

실행 결과:

값: 100
weak_ptr이 만료되었습니다.

참고사항

  • shared_ptr은 memory 헤더에 정의되어 있습니다.
  • make_shared를 사용하여 객체를 생성하는 것이 권장됩니다.
  • 참조 카운팅을 통해 메모리 누수를 방지합니다.
  • 순환 참조를 피하기 위해 weak_ptr을 사용할 수 있습니다.
  • 스레드 안전한 참조 카운팅을 제공합니다.
메서드 설명
use_count() 참조 카운트 반환
reset() 포인터 초기화
get() 원시 포인터 반환
swap() 다른 shared_ptr과 교환
operator* 역참조
operator-> 멤버 접근