Jump to content

Class containing itself


Recommended Posts

Hi,

I would like to know if a class can have an array of objects from the same class. For example if I have a class Human, can it holds an array of its children (they are humans too) ?

C++ equivalent:

class Human{

private :

list<Human> children;

}

I've tried it and it gives me the "Private data control of this class uses an illegal value for its default data ..." error. Is there a way around that or do I have to use inheritance or the composite pattern?

Thanks

Link to comment

Hi,

I would like to know if a class can have an array of objects from the same class. For example if I have a class Human, can it holds an array of its children (they are humans too) ?

C++ equivalent:

class Human{

private :

list<Human> children;

}

I've tried it and it gives me the "Private data control of this class uses an illegal value for its default data ..." error. Is there a way around that or do I have to use inheritance or the composite pattern?

Thanks

It may also be handy to state why you are trying to accomplish the above (use case), as someone maybe able to offer an alternative solution to your problem.

Link to comment

I posted List and Tree a while back: http://lavag.org/top...classes-for-85/

It becomes unstable around 1000 elements because it relies upon recursion. The DVR solution is much more complex and has the weirdness involved with references, but can go much deeper.

Note that a list of 1000 elements is pretty poor... but a tree of depth 1000 is 2^1000 elements, which should be more than enough. :-)

Link to comment

Thanks, I understand a little better now. But it's still way too complicated for what I want to do! It's not a binary tree, for sure my tree will never hold 1000 elements (and probably not even a 100!), and if I delete a node, its subtree is also deleted.

Link to comment

Try using a Variant to represent a tree. Make the attributes of the variant also be variants. And so on. You can model a tree of any shape/dimension this way.

Not to mention lookup on variant attributes is extremely fast thanks to some optimizations in the late 8.x (?) era.

Link to comment

Slightly off the original topic, but is there an advantage to using a DVR to store the child nodes, instead of storing the child nodes directly (using LVObject or some other common parent and then downcasting)?

Link to comment

You need a DVR tree when you need to do bidirectional operations. That is pretty common when you are modeling a real-world system like Marie is. Think of a family tree. Family Tree class contains all the family members. Essentially you traverse the Family tree until you find the family member you are interested. Then you can query who that member's parents, uncles, children are very quickly. This rocks if you need efficent code on a system that you understand well.

Link to comment

Yeah that's what I was looking for. I just don't understand what is the type of the children in the TreeNode class.

Yeah, when I made that it was entirely a workaround. I experimented with a few solutions and that was the one I liked best. Here is a really basic project that shows how to do what you want and it uses properties to make it look less janky.

Link to comment

You need a DVR tree when you need to do bidirectional operations. That is pretty common when you are modeling a real-world system like Marie is. Think of a family tree. Family Tree class contains all the family members. Essentially you traverse the Family tree until you find the family member you are interested. Then you can query who that member's parents, uncles, children are very quickly. This rocks if you need efficent code on a system that you understand well.

I understand the data structures, I've done the standard data structures in Java and C. What I don't understand is why you need the DVR. In a linked list you'd have a "previous" and "next" object, in a tree it's a bunch of "child" objects and a "parent" object. What is the advantage to using a DVR instead of embedding the objects directly? I implemented (but don't have the code for right now) a linked list this way and it worked fine, although I found that the only way I could get back to the front of the list was to have a "rewind" method that looped until it reached the start; does the DVR somehow solve this problem?

Link to comment

I knew there was interest in that question.

Finally I've redesign everything. What I haven't told is that my tree was supposed to represent rows in a postgres table. Each row has a foreign key pointing to the same table to represent its father (except for root). At first I wanted to load the whole tree, make the change on it and applied it to the database so if you wanted to cancel something in the process, the change would not have been made in the DB. Instead I decided to use the database properties like a transaction and delete on cascade. If the user decide to cancel everything, I rollback and no changes are made in the DB and if he decide to save, the commit is made. Also easy when you want to delete a subtree, you just have to delete its root and on cascade, everything pointing to it will be deleted. No recursive functions except for loading the tree. Eventually, if i have time, I could implement the Command pattern to have a undo/redo, but at the moment it's just a nice to have.

Now I see the use of my software conception class and that all the time spent on my class diagram is not lost. :D

Link to comment

I implemented (but don't have the code for right now) a linked list this way and it worked fine, although I found that the only way I could get back to the front of the list was to have a "rewind" method that looped until it reached the start; does the DVR somehow solve this problem?

Could you post your node class? I am not sure how your linked list solution could move both directions if you just embed the next and previous node directly in the current nodes data. A quick picture and I'll have the 'aha' moment. The DVR is just a crutch for not having a pointer, in a problem that I believe requires one. If the problem was unidirectional (top to bottom traversing) I think dataflow is the way to go.

Link to comment

Here you go. I pulled pieces from existing code that used a linked list with limited functionality, expanded it and removed the application-specific data (some items are still marked "Reaction" because I was tracking a list of chemical reactions that needed to be executed in a particular order, defined at run-time by reading from a file). There must be a more efficient way to do some of these operations, because they're incredibly slow. The "Test Linked List" VI generates 10 random numbers and then inserts them into the list in ascending order by iterating through the list until a greater value is found, then inserts the new value at that point. After generating the list, it iterates through the list and appends each number to an array. This is the part that's inexplicably slow - so slow you can see it adding about one number per second on a fast machine with plenty of RAM. I'd love to know how to fix that, just for my curiousity as I don't actually need this functionality in any application I'm working on right now. (LabVIEW 2011)

The LinkedList class (Prev and Next are of type LinkedParent from which LinkedList inherits)

post-3989-0-90621800-1332825154.png

Inserting a new node into the list

post-3989-0-67809100-1332825949_thumb.pn

Advancing through the list

post-3989-0-51607300-1332826053.png

"Rewinding" the list

post-3989-0-41839000-1332826109.png

Linked List.zip

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.