Marie Posted March 20, 2012 Report Share Posted March 20, 2012 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 Quote Link to comment
Mr Mike Posted March 20, 2012 Report Share Posted March 20, 2012 LabVIEW does not allow recursive type definitions. You can have objects of parent types in a child class, but you cannot have a class contain itself. Quote Link to comment
jgcode Posted March 20, 2012 Report Share Posted March 20, 2012 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. Quote Link to comment
Marie Posted March 20, 2012 Author Report Share Posted March 20, 2012 To represent a tree. I was trying to keep thing simple with the fact that the object keep a list of its own children. Quote Link to comment
jgcode Posted March 20, 2012 Report Share Posted March 20, 2012 To represent a tree. I was trying to keep thing simple with the fact that the object keep a list of its own children. This may be of interest? https://decibel.ni.com/content/docs/DOC-12668 Quote Link to comment
Marie Posted March 20, 2012 Author Report Share Posted March 20, 2012 Yeah that's what I was looking for. I just don't understand what is the type of the children in the TreeNode class. Quote Link to comment
jgcode Posted March 20, 2012 Report Share Posted March 20, 2012 Yeah that's what I was looking for. I just don't understand what is the type of the children in the TreeNode class. I think it's the workaround: Its a reference to a LabVIEW Data Object Which is updated during runtime Quote Link to comment
Aristos Queue Posted March 21, 2012 Report Share Posted March 21, 2012 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. :-) Quote Link to comment
Marie Posted March 21, 2012 Author Report Share Posted March 21, 2012 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. Quote Link to comment
John Lokanis Posted March 21, 2012 Report Share Posted March 21, 2012 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. 1 Quote Link to comment
asbo Posted March 21, 2012 Report Share Posted March 21, 2012 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. Quote Link to comment
ned Posted March 21, 2012 Report Share Posted March 21, 2012 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)? Quote Link to comment
GoGators Posted March 21, 2012 Report Share Posted March 21, 2012 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. Quote Link to comment
GoGators Posted March 21, 2012 Report Share Posted March 21, 2012 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. Quote Link to comment
ned Posted March 21, 2012 Report Share Posted March 21, 2012 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? Quote Link to comment
Marie Posted March 22, 2012 Author Report Share Posted March 22, 2012 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. Quote Link to comment
GoGators Posted March 26, 2012 Report Share Posted March 26, 2012 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. Quote Link to comment
ned Posted March 27, 2012 Report Share Posted March 27, 2012 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) Inserting a new node into the list Advancing through the list "Rewinding" the list Linked List.zip Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.