Travis said:
Thanks for the help. Maybe I am going about it the wrong way. So
basically what I'm wanting to do, is get a node in the tree based on
some criteria. I wanted tree to remain as reusable as possible so I
would like to avoid modifying it (it's a template, etc.).
So the tree is full of myNodeType I would like to be able to say
myNodeType *foundNode = MenuTreeObj->findNode(ID); // find based on ID
- or -
myNodeType *foundNode = MenuTreeObj->findNode(unique_name); // find
based on name
Is that even practical? What I had been doing in the past (since the
== makes determination based on name).
myNodeType *tmp = new myNodeType("unique_name_to_be_found");
myNodeType *foundNode = MenuTreeObj->findNode(tmp);
That changes the complexion of things a bit. You require a strict
ordering for a tree, so you can't use an either-or overload like I first
suggested.
It sounds like what you want to do requires two trees each one using a
different method for comparing. A simple overload of == won't do since
that code has no way of knowing which key you want to use when. The
choices would be to create two free functions that compare your objects
using the appropriate fields or you can create two member functions that
compare the appropriate fields.
As an example:
bool Cmpid(myNodeType * pA1, myNodeType * pA2)
{
return pA1->id == pA2->id;
}
-or-
class myNodeType
{
bool Cmpid(myNodeType *pA)
{
return id == pA->id;
}
};
And much the same for the name field.
If you don't have to roll your own structures, I would look up
boost::multiindex from
www.boost.org as that is exactly what that class
is for... A container with multiple indexes. If you can't use 3rd
party software, but can use stl classes, then I would replace your trees
with std::map or std::set. maps are much easier in this case since your
keys are a subset of your class type. Using stl you would have two maps
one for the id and one for the name. These would then contain a pointer
to the actual object you are trying to find.
Another possibility might be (depending upon what your id is for....) to
store pointers to your objects in a vector and use the index as the id
of the object. Then create a map as an index to find the object by
name. Then looking up by index becomes simply verifying the index is in
range, and looking in that slot to see if an object has been assigned.
If it is, you return it. Finding by name would involve doing a lookup
in the map by name.
There are lots of ways to organize these things for proper memory
management, but whatever you do, make sure that the indexes and the
actual existence of the objects are kept in sync or you will get some
really wierd errors. In fact, I would suggest that you wrap all this
indexing logic along with the ownership of the objects being indexed
into a class of its own. That way you can make sure that you don't
accidentally forget a step later on when you have forgotten the
complexities of this stuff.
joe