> The first mistake is using shared_ptr to begin with.
Yes, definitively! Using shared pointers can hide bad design.
There are some cases when it is hard to choose the owner of data. Two examples come to my mind. The first are directed graphs: what owns nodes? The second example are parsers, sometimes AST subgraphs must be assigned to extra structures during further processing (type analysis, code generation and so on).
A rule of thumb that I use is, if you cannot see the owner, then you're probably focusing too narrowly. For a directed graph, which is a "sea of nodes" with no real ordering, I would have the "graph" object own all its nodes; for an AST, if it is truly a tree, then the parent owns its children, or otherwise see the directed graph case.
The solution with a graph object looks nice, but when you allow some graph operations, than subgraphs could be shared among many (new) graphs. So, another level of sharing. I can't find any better solution for this problem.
Yes, definitively! Using shared pointers can hide bad design.
There are some cases when it is hard to choose the owner of data. Two examples come to my mind. The first are directed graphs: what owns nodes? The second example are parsers, sometimes AST subgraphs must be assigned to extra structures during further processing (type analysis, code generation and so on).