Question

I have encountered a class that requires a std::weak_ptr as a constructor argument. The problem is that the weak pointer must be pointing to a shared_ptr that owns the instance being created. I cannot figure out how to pass said pointer, since the shared_ptr itself is only constructed or assigned to after the class has been constructed.

struct SomeClass
{
    SomeClass(std::weak_ptr<SomeClass> ptrToThis){...}
    ...
};

I've tried the following for passing the weak_ptr to the constructor, but it fails (I presume this happens because the original shared_ptr no longer uses the same sentry object internally after getting assigned to)

int main()
{
    std::shared_ptr<SomeClass> shared;
    std::weak_ptr<SomeClass> weak;
    weak = shared;
    shared = std::make_shared<SomeClass>(weak);
    //this prints "1" (true)
    std::cout << weak.expired();
    return 0;
}

How could this be corrected? Since I can modify the original class, should I modify it somehow, for example adding a separate function for setting the value of the weak_ptr after construction?

Was it helpful?

Solution

You might be better off using std::enable_shared_from_this, which was designed for situations like this.

To use it, derive your class from it. It will store a std::weak_ptr which will be initialised to point to the object the first time a std::shared_ptr pointing to that object is created:

struct SomeClass : public std::enable_shared_from_this<SomeClass>
{
  //...
};

If you need to make sure a std::shared_ptr to your class always exists, you can make all of its constructors private (or protected, as applicable) and give it a public static creation function returning a std::shared_ptr:

struct SomeClass : public std::enable_shared_from_this<SomeClass>
{
    std::shared_ptr<SomeClass> create()
    { return std::make_shared<SomeClass>(); }

private:
    SomeClass()
    {}
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top