21. std::enable_shared_from_this 와 shared_from_this() 의 내부 동작

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// [주제] std::enable_shared_from_this 와 shared_from_this() 의 내부 동작
// 비동기 수신 완료 콜백/타이머가 처리 중 자기 세션 객체를 안전하게 붙잡으려면
// "자신을 가리키는 shared_ptr" 이 필요하다(핸들러가 사는 동안 객체 수명 연장).
// std::enable_shared_from_this 를 상속하면 shared_from_this() 로 이를 얻는다.
//
// [과제]
//   1) 출력 라인 1~5 가 각각 무엇을 출력할지 예측하라.
//   2) shared_from_this() 가 어떻게 "자신을 가리키는 shared_ptr" 을 만들어
//      내는지(기저 클래스가 품은 무엇을 쓰는지), 그것이 언제 채워지는지,
//      그래서 왜 스택 객체나 아직 shared_ptr 로 소유되기 전(생성자 포함)에
//      호출하면 실패하는지 내부 동작으로 설명하라.
//   (내부 동작 설명은 answer.md 참조 — 먼저 스스로 예측/설명해 볼 것.)

#include <iostream>
#include <memory>

struct Session : std::enable_shared_from_this<Session> {
    int id;
    explicit Session(int i) : id(i) {}
    std::shared_ptr<Session> self() { return shared_from_this(); }
};

int main() {
    auto sp = std::make_shared<Session>(1);
    std::cout << "1: " << sp.use_count() << "\n";

    auto s2 = sp->self();
    std::cout << "2: " << sp.use_count() << "\n";
    std::cout << "3: " << (s2.get() == sp.get()) << "\n";

    std::weak_ptr<Session> w = sp->weak_from_this();
    std::cout << "4: " << (w.lock().get() == sp.get()) << "\n";

    Session local(2);   // 스택 객체 — shared_ptr 로 소유되지 않음
    try {
        auto bad = local.self();
        (void)bad;
        std::cout << "5: no throw\n";
    } catch (const std::bad_weak_ptr&) {
        std::cout << "5: bad_weak_ptr\n";
    }
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.