enable_shared_from_this — std::enable_shared_from_this

enable_shared_from_this — std::enable_shared_from_this

std::enable_shared_from_this는 현재 std::shared_ptr(이름 pt)가 관리하는 객체 t가, t의 소유권을 pt공유하는 추가 std::shared_ptr 인스턴스(pt1, pt2 등)를 안전하게 생성할 수 있게 해주는 도구예요.

std::enable_shared_from_this<T>를 공개 상속하면 타입 Tshared_from_this 멤버 함수가 제공돼요.

출처: cppreference

본문

// <memory> 헤더, C++11
template< class T >
class enable_shared_from_this;

사용 예

#include <memory>
#include <iostream>

struct Good : std::enable_shared_from_this<Good> {
    std::shared_ptr<Good> getptr() {
        return shared_from_this();
    }
};

int main() {
    std::shared_ptr<Good> sp1 = std::make_shared<Good>();
    std::shared_ptr<Good> sp2 = sp1->getptr();
    // sp1과 sp2가 같은 객체를 공유
    std::cout << (sp1 == sp2) << '\n';   // 1
}

왜 필요한가

멤버 함수 안에서 thisstd::shared_ptr(this)를 만들면 위험해요.

struct Bad {
    std::shared_ptr<Bad> getptr() {
        return std::shared_ptr<Bad>(this);   // 위험: 별도의 소유권 → 이중 해제
    }
};
// getptr()이 만든 shared_ptr은 원본과 무관한 소유권을 가져,
// release/해제 시 이중 free 또는 무효한 접근 발생

enable_shared_from_this를 상속하면 shared_from_this()같은 소유권 그룹shared_ptr을 반환해요. 객체는 std::shared_ptr로 관리되어야 하며, 그렇지 않으면 동작이 정의되지 않아요 (std::bad_weak_ptr가 던져질 수 있어요).

규칙

  • 객체가 실제로 std::shared_ptr에 의해 소유될 때만 shared_from_this()를 호출해야 해요.
  • C++17부터는 std::shared_ptr<T>(this)처럼 명시적으로 만드는 대신 shared_from_this()를 쓰는 것이 안전해요.
  • 멀티스레드에서 shared_from_this()는 안전하도록 보장돼요.
// 뮤텍스 등 자기 자신의 shared_ptr이 필요한 콜백 시나리오
struct Task : std::enable_shared_from_this<Task> {
    void run();
    void schedule() {
        auto self = shared_from_this();
        // self를 캡처해 수명을 안전하게 유지
    }
};

enable_shared_from_this는 객체가 스스로의 shared_ptr을 만들어야 하는 비동기 콜백·수명 연장 패턴에서 핵심적인 도구예요.

더 알아보기 (Learn more)

cppreference