Search code examples
c++c++11shared-ptr

How do I hand out weak_ptrs to this in my constructor?


I'm creating a class that will be part of a DAG. The constructor will take pointers to other instances and use them to initialize a dependency list.
After the dependency list is initialized, it can only ever be shortened - the instance can never be added as a dependency of itself or any of its children.

::std::shared_ptr is a natural for handling this. Reference counts were made for handling DAGs.

Unfortunately, the dependencies need to know their dependents - when a dependency is updated, it needs to tell all of its dependents.
This creates a trivial cycle that can be broken with ::std::weak_ptr. The dependencies can just forget about dependents that go away.

But I cannot find a way for a dependent to create a ::std::weak_ptr to itself while it's being constructed.

This does not work:

object::object(shared_ptr<object> dependency)
{
     weak_ptr<object> me = shared_from_this();
     dependency->add_dependent(me);
     dependencies_.push_back(dependency);
}

That code results in the destructor being called before the constructor exits.

Is there a good way to handle this problem? I'm perfectly happy with a C++11-only solution.


Solution

  • Instead of a constructor, use a function to build the nodes of your graph.

    std::shared_ptr<Node> mk_node(std::vector<std::shared_ptr<Node>> const &dependencies)
    {
        std::shared_ptr<Node> np(new Node(dependencies));
        for (size_t i=0; i<dependencies.size(); i++)
            dependencies[i].add_dependent(np);       // makes a weak_ptr copy of np
        return np;
    }
    

    If you make this a static member function or a friend of your Node class, you can make the actual constructor private.