#### Archived

This topic is now archived and is closed to further replies.

# Preferred method of accessing nested data

## Recommended Posts

Another philosophical question, I''m afraid. Just trying to get some opinions. Say you have a hierarchy of objects, each one contained by the previous. Eg. Country contains Forests Forest contains Trees Tree contains Leaves Assuming all the data members are private, how do you access Leaves from outside the Country class? For example, if the algorithm was:
for each country
show the details for the biggest leaf in that country

Do you write this as cascading accessors? eg. Country::GetBiggestLeaf() calls Forest::GetBiggestLeaf for each forest, which in turn calls Tree:GetBiggestLeaf? Or maybe provide accessors to the collections themselves, and then iterate through them? eg. Country::GetBeginForest() and Country::GetEndForest() Although my current problem is not game-related, I''ve had this apply to games before, such as when dealing with an AnimationFrame that belongs to an Animation that belongs to a Sprite that belongs to a Character who needs to draw itself. (Or return a graphic for someone else to draw; whatever.) Is there an idea I''m missing, apart from the basic 2 of "write a set of nested functions for each task" or "expose iterators and write a nested loop for each task"? [ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

##### Share on other sites
I''m doing this for my current project - I''ve got this setup:

Creature has
Chemistry, Brain which have

I do a mix. For a lot of things I provide accessors - for instance, a Creature method that calls another accessor on the Brain.
I also expose a method of Creature called brain(), because accessing the brain is quite common, and otherwise I''d have a whole load of methods which are simply redirectors.

If you''re wanting to directly access a subobject, and there''s only one (or an array), you could provide a const pointer accessor (perhaps with array bounds checking).
Otherwise, and especially if you''re doing something like GetBiggestLeaf, I''d provide a direct method in Forest and Country. Hide the implementation. That way if you introduce Plants into Forest as well as Trees, you only have to rewrite GetBiggestLeaf once (or not at all...).

Anyway, that''s my thinking

I don''t think there are any missing options.

##### Share on other sites
quote:
Original post by Kylotan
Another philosophical question, I''m afraid. Just trying to get some opinions.

Say you have a hierarchy of objects, each one contained by the previous. Eg.

Country contains Forests
Forest contains Trees
Tree contains Leaves

Assuming all the data members are private, how do you access Leaves from outside the Country class?

Using delegation! But there are obviously other strategies. If you have a tree structure and you are using C++, you can consider providing for visitation down the nodes, accepting a functor at each node. Or perhaps you''d want to go all STL and expose suitable iterators, although you might also need some specific algorithms to selectively traverse the structure. It really depends on the specific case.
quote:

For example, if the algorithm was:

for each country    show the details for the biggest leaf in that country

You could perhaps have a visitor traversing the tree, checking if the node is a country and if so, have it launch another visitation down that branch. Or you might consider that an undesirable time-penalty, so you could layer indexing structures over the underlying tree in order to enable efficient queries to be performed. It all depends on what sort of time-space trade-off you are after.
quote:

Although my current problem is not game-related, I''ve had this apply to games before, such as when dealing with an AnimationFrame that belongs to an Animation that belongs to a Sprite that belongs to a Character who needs to draw itself. (Or return a graphic for someone else to draw; whatever.)

For this sort of case, check out the Law of Demeter, which in a nutshell says "don''t hard-code object relationships into call-sites". The answer is to delegate.

In general, I don''t think it''s possible to provide a definitive answer to your question. Do whatever seems right for the specific circumstances.

##### Share on other sites
Seems wrong to have the country know anything about leaves. It is just a container for forests. If it contains forests, cities, fields, rivers, mountains and a bunch of other stuff then it is going to get rather cluttered. That is just basic access. When you get into combinations and permutation it is going to get real nasty. You can get around some of that, but that begs the question why. Is there really a benefit to the user not knowing a leaf is part of a tree? Just how little can they know about their data and make practical use of the data? How would you even know to ask for the biggest leaf on the smallest tree in the biggest forest if you didn''t even know that relationship existed?

##### Share on other sites
quote:
Original post by LilBudyWizer
How would you even know to ask for the biggest leaf on the smallest tree in the biggest forest if you didn''t even know that relationship existed?

Yeah... the question is, do you need to know the exact nature of that relationship and exploit that via direct accessing of the members and members-of-members, or do you just need to know that such a relationship exists and write functions to handle that,propagating requests down the chain?

Reading these comments, I''m thinking that in C++ it''s probably best to propagate the functions downwards, so you don''t (need to ) know how the classes are related, and only deal with the top-level class''s interface. If it was Python however, I might be tempted to use the functional approach since it might work equally well and be more succinct.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

• ### Forum Statistics

• Total Topics
628333
• Total Posts
2982139

• 9
• 24
• 9
• 9
• 13