[C++]

shared_from_this, enable_shared_from_this

럭키🍀 2024. 9. 6. 12:04

shared_ptr로 만들어질 객체에 대해서 this와 같은 기능인 shared_from_this 가능하도록
클래스를 만들때 enable_shared_from_this<자기클래스 타입>를 상속받게 만든다.

-shared_ptr로 만들어질 객체에 대해 자신을 가리킬 때 직접 this를 사용하지 않고 shared_from_this를 사용하는 이유는
this키워드는 원시포인터로 shared_ptr의 참조카운트에 카운트 되지 않기 떄문이다. (그래서 this를 사용하면 같은 객체를 관리하는 컨트롤 블록이 하나 더 생길 수 있고 이는 미정의 동작을 만들 수 있다.)

-shared_from_this는 내부적으로 weak_ptr을 사용해 객체의 shared_ptr을 관리한다.

-shared_from_this의 사용으로 생기는 weak_ptr는 기존 이 객체를 관리하는 컨트롤 블록에 기록하는데, 즉 shared_from_this를 사용하는 시점에 이미 이 객체를 가리키는 shared_ptr이 있다고 가정하는 것이다. 그래서 shared_ptr이 생성되기 전에 shared_from_this가 호출되는 것을 방지하기 위해 주로 enable_shared_from_this를 상속받은 타입에는 기본으로 제공되는 생성자들을 private으로 만들고 shared_ptr을 반환하는 생성함수(아래에선 getSharedPtr())를 만들어둔다. 

#include <memory>
#include <iostream>
using namespace std;

class MyClass : public std::enable_shared_from_this<MyClass> {
public:
    std::shared_ptr<MyClass> getSharedPtr() 
    {
        std::shared_ptr<MyClass> s = static_pointer_cast<MyClass>(shared_from_this());
        return s;//자기자신의 포인터를 호출
    }

    void show() 
    {
        std::cout << "MyClass::show() called\n";
    }
};

int main()
{
    // shared_ptr를 통해 객체를 생성
    std::shared_ptr<MyClass> p1 = std::make_shared<MyClass>();

    std::cout << "Reference count: " << p1.use_count() << "\n"; // 참조 카운트 출력

    // 객체 자신에 대한 shared_ptr를 얻음
    std::shared_ptr<MyClass> p2 = p1->getSharedPtr();

    std::cout << "Reference count: " << p1.use_count() << "\n"; // 참조 카운트 출력

    // 두 shared_ptr가 같은 객체를 가리키는지 확인
    if (p1 == p2) 
    {
        std::cout << "p1 and p2 are pointing to the same object\n";
    }


    return 0;
}