Sign in to follow this  
CableGuy

Scene graphs and shared_ptr

Recommended Posts

Hello,

I've created a simple scene graph implementation and have a problem with cyclic referencing. In my implementation you never hold a node or reference to a node but rather a NodePtr which is just a typedef for shared_ptr<Node>. Also each node stores internally a list of all it's children(a vector of NodePtr) and a parent which is also a NodePtr. As you can see this leads to a cyclic referencing of nodes and their parents.
I tried to come up with ideas that might solve this but still retain the same interface( using shared pointers) but the only solution I could come up with is having some kind of a SceneGraph class that hold a NodePtr to the root and when this object is destroyed iterate over the graph and break all the connections(lets assume that every NodePtr can only be a member of a single SceneGraph). I must say I'm not too fond of this solution so if anyone has got a better idea please share.

Thanks.

Share this post


Link to post
Share on other sites
First a question; why does the child need to know about its parent?

Second; if the child really does need to know then is it valid for the child to exist without a parent? If not then a reference to the parent is probably a better idea than a pointer. If the object can be reassigned to another parent then a weak_ptr might be the correct choice.

End of the day it is all about ownership; shared_ptr are for when ownership is truely shared. Chances are shared_ptr is technically the wrong tool for the job here as the ownship is scoped and maybe transferable but not shareable in any logical sense.

Don't get me wrong, shared_ptr is a useful tool however it isn't always the right tool.

Share this post


Link to post
Share on other sites
1. Nodes need a pointer to their parent since for example when their transformation changes they not to mark all bounding volumes up the tree as invalid.
2. A child can exist without it's parent since a child is just another node( it can become a root node or attached to another one)

the weak_ptr idea sounds nice since there is no point in having a pointer to the middle of the graph but nothing to it's upper part, although technically possible which will
result in the weak_ptr being invalidated.

I agreet that shared_ptr might not be the best tool for the job and that the ownership is not shareable since a child does not "own" it parent, but the problem still stands.
I need memory to be released when nothing points to it and I don't want to created some sophisticated garbage collection mechanism nor store a pointer to all nodes
ever allocated in some central list.

Thanks for your answer.

Share this post


Link to post
Share on other sites
For holding the parent the case could be made for a raw pointer; if a parent is released then it's children should be released so you won't get dangling pointers and children will either have a live pointer to their parent or a null if they have no parent.

There is no memory clean up issue as parents can still hold children by shared_ptr which ensures automatic clean up. Also 'boost::scoped_ptr' might be a better fit for holding references to children, although it might require some extra work if you are copying instances around as it is non-copyable via the assignment/copy-constructor.

Share this post


Link to post
Share on other sites
[quote]For holding the parent the case could be made for a raw pointer; if a parent is released then it's children should be released so you won't get dangling pointers and children will either have a live pointer to their parent or a null if they have no parent.[/quote] But if there are two instances: P which is the parent of C. And there are two pointers, one pointing to P and the other one to C.
When the first pointer goes out of scope P will get destroyed but it is actually still needed since there is a pointer to C and P is it's parent. But then again I can't think of this scenario happening in reality.

Will have to read on boost::scoped_ptr...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this