I have a directed acyclic graph, composed of Node objects. Each node has a list of std::shared_ptrs to other nodes, which are its children in the graph. I have lots of useful methods I need, such as inserting/emplacing/reparenting nodes, testing if a node is an ancestor of another, etc. Some are standard STL-like methods, and some are specific to directed acyclic graphs and specific to my needs.
The question is, When such a method takes a node as a parameter, should it take a reference? of a weak_ptr? or a shared_ptr? I tried to examine use cases but it’s hard to tell. What’s the best design here? I’m new to smart pointers and I’m not sure what’s the best choice. Should I treat shared_ptr<Node> as “the representation” of node objects? Or maybe the way to choose is more sophisticated?
Thanks in advance
Only pass a
shared_ptr(by value) or copy it when the set of owners is meaningfully extended. It’s safe, and preferred, to pass pointers when dealing with nodes as pure information.Note the
std::enable_shared_from_thisfacility to retrieve the correctstd::shared_ptrfrom any graph object. With that base class, a valid naked pointer and a shared pointer are essentially equivalent. I’m not sure how much, if any, overhead it adds. (It definitely ensures that there will be no additional heap fragmentation, whichstd::make_sharedalso does.)Passing
shared_ptranywhere is just an optimization of functionality elegantly provided byshared_from_this. But when you do, pass them byconstreference, since they are just providing information without actively arbitrating ownership.