티스토리 뷰

2023.02.24 2019년의 내가 제대로 알지 못했던 내용을 추가

 

기본적으로 shared_from_this 는 shared_ptr 로 만든 객체를 다른 함수에 넘기다 보니 rawPointer 로 변환하여 넘긴 상황에서 다시 shared_ptr 로 변환하는 용도로 사용한다.

 

기본적으로 public std::enable_shared_from_this 를 상속받은 클래스는 raw pointer 에서 shared_from_this 를 통해 shared_ptr 객체를 얻을 수 있지만, 이 객체는 이미 shared_ptr 로 관리되고 있는 객체여야 한다.

 

아래 예시를 살펴보자

class Hi
    : public std::enable_shared_from_this<Hi>
{
public:
    Hi()
    {
        std::cout << "construct\n";
    }
    ~Hi()
    {
        std::cout << "destruct\n";
    }

    std::shared_ptr<Hi> getptr()
    {
        return shared_from_this();
    }
};

int main()
{
    Hi* h = new Hi;
    auto x = h->getptr(); // 여기서 크래시가 난다

    return 0;
}

main 의 h->getptr 을 하게 되면 크래시가 나는데, 이는 shared_ptr 로 관리되는 객체가 아니라 그저 raw pointer 이기 때문에 크래시가 난다. 이 상황에서 크래시가 나지 않게 해야한다면 다음과 같이 수정하면 된다.

 

int main()
{
    // 1. raw pointer 로 생성되었지만 shared_ptr 객체로 만든다.
    Hi* h = new Hi;
    std::shared_ptr<Hi> ptr( h );
    auto x = h->getptr();

    // 2. 처음부터 shared_ptr 객체로 만든다.
    std::shared_ptr<Hi> ptr2 = std::make_shared<Hi>();
    Hi* rawPointer = ptr2.get(); // rawPointer 이지만 이미 shared_ptr 로 관리되는 객체이다.
    auto ptr3 = rawPointer->getptr();

    return 0;
}

내가 생각하는 가장 좋은 방법은 shared_from_this 를 사용해야 하는 클래스는, 외부에서 접근할 수 있는 생성자를 막고 shared_ptr 객체를 반환하는 함수로 생성하는것이 가장 좋은 것 같다.

 

https://stackoverflow.com/questions/27697973/shared-from-this-causing-bad-weak-ptr

 

shared_from_this causing bad_weak_ptr

I am trying to keep a list of connected clients in asio. I have adapted the chat server example from the docs (http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/example/cpp03/chat/chat_serve...

stackoverflow.com

--

 

이전 블로그 글에서 std::enable_shared_from_this 앞에 public을 붙여 사용했던 적이 있어서 공부한 내용

 

이렇게 하면, 따로 getptr 함수를 만들지 않아도 되지만, 제대로 Initialize 되지 않은 shared_ptr을 사용 할 수도 있기 때문에 주의해서 사용해야 한다. 이는 enable_shared_from_this 의 구현 때문인데, c++ 버전 마다 다르게 동작 해서 찾아본 글도 첨부한다.

 

Not in C++14; the only operation that enable_shared_from_this supports is creating a shared_ptr. Now, enable_shared_from_this should have sufficient information to construct a weak_ptr directly. But you can't do it from the outside, as the class doesn't expose its implementation details to you.

C++17 has support for fetching a weak_ptr from an enable_shared_from_this class via weak_from_this.

 

https://stackoverflow.com/questions/39937112/stdenable-shared-from-this-public-vs-private

 

https://stackoverflow.com/questions/38284296/is-there-a-weak-ptr-equivalent-to-shared-from-this

댓글