developer tip

std :: shared_ptr of this

optionbox 2020. 10. 12. 07:27
반응형

std :: shared_ptr of this


저는 현재 스마트 포인터 사용법을 배우려고합니다. 그러나 몇 가지 실험을 수행하는 동안 포화 솔루션을 찾을 수없는 다음 상황을 발견했습니다.

클래스 A의 오브젝트가 클래스 B (자식)의 오브젝트의 상위가되지만 둘 다 서로를 알아야한다고 가정하십시오.

class A;
class B;

class A
{
public:
    void addChild(std::shared_ptr<B> child)
    {
        children->push_back(child);

        // How to do pass the pointer correctly?
        // child->setParent(this);  // wrong
        //                  ^^^^
    }

private:        
    std::list<std::shared_ptr<B>> children;
};

class B
{
public:
    setParent(std::shared_ptr<A> parent)
    {
        this->parent = parent;
    };

private:
    std::shared_ptr<A> parent;
};

문제는 클래스 A의 객체가 어떻게 std::shared_ptr자신의 ( this)를 자식에게 전달할 수 있습니까?

Boost 공유 포인터 ( Getting a boost::shared_ptrforthis )에 대한 솔루션 이 있지만 std::스마트 포인터를 사용하여이를 처리하는 방법은 무엇입니까?


std::enable_shared_from_this바로이 목적을 위해. 당신은 그것으로부터 상속하고 당신은 .shared_from_this()클래스 내부에서 호출 할 수 있습니다 . 또한 여기에서 리소스 누출로 이어질 수있는 순환 종속성을 생성하고 있습니다. 이 문제는 std::weak_ptr. 따라서 코드는 다음과 같이 보일 수 있습니다 (자녀가 부모의 존재에 의존하고 그 반대가 아니라고 가정).

class A;
class B;

class A
    : public std::enable_shared_from_this<A>
{
public:
    void addChild(std::shared_ptr<B> child)
    {
        children.push_back(child);

        // like this
        child->setParent(shared_from_this());  // ok
        //               ^^^^^^^^^^^^^^^^^^
    }

private:     
    // note weak_ptr   
    std::list<std::weak_ptr<B>> children;
    //             ^^^^^^^^
};

class B
{
public:
    void setParent(std::shared_ptr<A> parent)
    {
        this->parent = parent;
    }

private:
    std::shared_ptr<A> parent;
};

그러나 호출 .shared_from_this()하려면 호출 시점에서 this소유 해야합니다 std::shared_ptr. 이는 더 이상 스택에 이러한 객체를 만들 수 없으며 일반적으로.shared_from_this() 생성자 또는 소멸자 내에서 호출 할 수 없음을 의미합니다 .


스마트 포인터에 대한 오해에서 비롯된 것처럼 보이는 디자인에 몇 가지 문제가 있습니다.

Smart pointers are used to declare ownership. You are breaking this by declaring that both the parents owns all children, but also that each child own it's parent. Both can't be true.

Also, you are returning a weak pointer in getChild(). By doing so, you are declaring that the caller shouldn't care about the ownership. Now this can be very limiting, but also by doing so, you must make sure that the child in question won't get destroyed while any weak pointers are still held, if you would use a smart pointer, it would get sorted out by itself.

And the final thing. Usually, when you are accepting new entities, you should usually accept raw pointers. Smart pointer can have their own meaning for swapping children between parents, but for general usage, you should accept raw pointers.

참고URL : https://stackoverflow.com/questions/11711034/stdshared-ptr-of-this

반응형