Jump to content

LV OOP override-vi & polymorphism?


Recommended Posts

Hi all,

I'm just starting using oop features of LV8.5. Until now I only used C++.

Do I have in LV really the possibility to use a child's override VI to OVERRIDE the functionallity of a base class vi?

Or is it only possible to add functionality to the by "call parent method" added base class vi?

So is the code of the base vi executed when executing the child's vi?

Thank You for any reply!

A little example, if possible would be very very appreciated!

Stefan

Link to comment

QUOTE(Milchbilch @ Oct 12 2007, 10:44 AM)

Do I have in LV really the possibility to use a child's override VI to OVERRIDE the functionallity of a base class vi?

Or is it only possible to add functionality to the by "call parent method" added base class vi?

So is the code of the base vi executed when executing the child's vi?

Yes, you can override VIs defined in parent classes. LabVIEWs "dynamic dispatch VI" behaves like C++ "virtual member function".

I think you can simply make your own example.

Jan

Link to comment

QUOTE(Milchbilch @ Oct 12 2007, 10:44 AM)

Do I have in LV really the possibility to use a child's override VI to OVERRIDE the functionallity of a base class vi?

So is the code of the base vi executed when executing the child's vi?

If you call the parent (=base) class method, the child (=derived) class method will actually be executed, as it overrides the base class method. Just like you're used to in C++.

Joris

Link to comment

QUOTE(Milchbilch @ Oct 12 2007, 11:44 AM)

So is the code of the base vi executed when executing the child's vi?

If you have a wire of type parent class that contains a child class instance and the wire terminates to dynamic dispatch input of your parent class member VI, then the child class member VI with the same name is executed instead if one exists. If on this child class VI block diagram, there is a 'call parent method' node, then and only then the parent method is called as well. The parent method in this case behaves as if it was a regular subVI on the block diagram of the child method. If immediate parent doesn't implement this method but the method is implemented in an ancestor class, then the method of closest ancestor is called with the call parent method primitive.

Tomi

Link to comment

Generally, we can create an override method for extension or replacement of the parent method. (The parent and child methods must have dynamic terminals and identical--except for the class objects--connector panes.) In LabVIEW 8.5 (nicely improved from 8.2.1 in the options availabe!) when we right-click on a child class and select New... VI for Override... from the shortcut menu the VI template used is better suited for extension. (There is already a call to the parent method. One can add further behavior to the block diagram.)

The question is, what if we want to create an override VI that we will replace the parent VI method's functionality? In LabVIEW 8.5 we can do this as follows:

1) Create an override VI as above, delete the call to the parent method, and add the functionality to the block diagram. (Unfortunately the template isn't set up as nicely for this as it was for the original VI. We have to add space and a case structure to get to the same place.)

2) Create a New... VI from Dynamic Dispatch Template in the child class. This is probably the easiest path currently. The drawback here is that the connector pane may very well not be the same as it was in the parent VI. (In particular, if we had any inputs or outputs that aren't part of the default template in our parent VI, then the connector panes won't match.)

3) Save a copy of the VI to replace from the parent class to the child class. Unfortunately we have to replace the parent class objects manually with the child class objects, update the labels (a separate step), and remove any existing code we don't want.

These are the paths I know to accomplish this. Solution 2 seems to be the simplest solution for me, but it's not great. Hopefully the next LabVIEW release will have a New... VI for Override for Replacement option that will combine the best parts of options 1)--ready-made connector pane and 2)--code-ready template with empty case structure. Personally I would prefer this for the override template in any case. I'd like to have the case structure and add the call to parent method wherever it is appropriate.

Link to comment

QUOTE(Paul_at_Lowell @ Oct 12 2007, 08:00 PM)

Generally, we can create an override method for extension or replacement of the parent method. (The parent and child methods must have dynamic terminals and identical--except for the class objects--connector panes.) In LabVIEW 8.5 (nicely improved from 8.2.1 in the options availabe!) when we right-click on a child class and select New... VI for Override... from the shortcut menu the VI template used is better suited for extension. (There is already a call to the parent method. One can add further behavior to the block diagram.)

The question is, what if we want to create an override VI that we will replace the parent VI method's functionality? In LabVIEW 8.5 we can do this as follows:

1) Create an override VI as above, delete the call to the parent method, and add the functionality to the block diagram. (Unfortunately the template isn't set up as nicely for this as it was for the original VI. We have to add space and a case structure to get to the same place.)

2) Create a New... VI from Dynamic Dispatch Template in the child class. This is probably the easiest path currently. The drawback here is that the connector pane may very well not be the same as it was in the parent VI. (In particular, if we had any inputs or outputs that aren't part of the default template in our parent VI, then the connector panes won't match.)

3) Save a copy of the VI to replace from the parent class to the child class. Unfortunately we have to replace the parent class objects manually with the child class objects, update the labels (a separate step), and remove any existing code we don't want.

These are the paths I know to accomplish this. Solution 2 seems to be the simplest solution for me, but it's not great. Hopefully the next LabVIEW release will have a New... VI for Override for Replacement option that will combine the best parts of options 1)--ready-made connector pane and 2)--code-ready template with empty case structure. Personally I would prefer this for the override template in any case. I'd like to have the case structure and add the call to parent method wherever it is appropriate.

Would you expect that the new VI would have a copy of the parent's code (essentially a Save As with patched up object references) or do you just want a case structure INSTEAD of the Call Parent Node?

Link to comment

QUOTE(gmart @ Oct 15 2007, 08:04 AM)

Would you expect that the new VI would have a copy of the parent's code (essentially a Save As with patched up object references) or do you just want a case structure INSTEAD of the Call Parent Node?

Hmm.... There are times when each would be useful, to be sure. In my experience a blank case structure (the second option you describe) is more frequently applicable by far (probably by a factor of 20), so I'd much prefer that option. (I consider this a must have for LVOOP. An option to create a version with a copy of the parent's code would be a nice to have alternative in addition, but just a nice to have.)

Link to comment

QUOTE(Paul_at_Lowell @ Oct 12 2007, 08:00 PM)

I love customers that make suggestions like this! :-)

I don't know if your idea will make it through the feature pipe anytime soon, but your comment has provided good food for thought.

Curious enough ... I spent a chunk of time writing a Linked List in LV (you can read about it http://forums.lavag.org/index.php?showtopic=8914&view=findpost&p=37007' target="_blank">here) and I was trying to delete error handling from a series of VIs. Popping up on a host of VIs to remove the case structure, then delete the FP terminals, then remove the broken wires, all without accidentally wiping out the useful code.

That experience is one I've had before. But having done that just yesterday, in combination with your comments about the difficulty of adding error handling to a VI, makes me wonder about better ways to tell a VI to handle errors.

Don't reply to this idea here. I don't want to hijack the thread. But at some point we should have a discussion about adding code to a VI that doesn't necessarily involve modifying the diagram (like an option for an "implied" error case structure). But let the idea marinate in your mind for a few weeks.

Link to comment

QUOTE(Paul_at_Lowell @ Oct 15 2007, 09:39 AM)

Hmm.... There are times when each would be useful, to be sure. In my experience a blank case structure (the second option you describe) is more frequently applicable by far (probably by a factor of 20), so I'd much prefer that option. (I consider this a must have for LVOOP. An option to create a version with a copy of the parent's code would be a nice to have alternative in addition, but just a nice to have.)

I agree with you. I think there are use cases where copying the entire implementation of the parent would be useful, but I think it's very rare and I also think it's a bad practice to ENCOURAGE. I'd hate for people to accidentally end up with a maintenance nightmare (i.e. having to go fix 20 different places where they did the same thing, when it could have been nicely wrapped up in a call parent node) because we made it too easy to make a bunch of copies of their code. So, I agree that a blank "template" makes more sense.

However, oddly enough, what may seem like the easier solution (creating an empty case structure as opposed to copying all the code) is actually a more difficult problem to solve. As AQ mentioned, sometimes people don't have/want error handling in their VIs. So, programmatically, what would we wire into the case structure? What's so nice (from a usability standpoint) about the Call Parent Node, and even copying the entire implementation for that matter, is that there's no guesswork about what the user wants. With the Call Parent Node, what we create is guaranteed to run and give them the same behavior as a starting point for them to then add subclass-specific functionality.

We have also considered having an error case structure in the new Override VI which uses the Call Parent Node (CPN). Assuming there was no "what if there's no error handling" problem, we'd still have to guess about whether users would want 1) to have the CPN inside the case structure, 2) to call the CPN first and then wire the error out into a case structure or 3) to have a case structure with the error wired through into a CPN called after the specialized code. If we put the CPN inside the case structure, most users would probably still need to drop an additional case structure inside the first to check the error coming out of the CPN, right? So, it doesn't seem like there's a one-size-fits-all solution.

Thoughts?

Link to comment

QUOTE(Robbie Gehbauer @ Oct 15 2007, 10:33 AM)

We have also considered having an error case structure in the new Override VI which uses the Call Parent Node (CPN). Assuming there was no "what if there's no error handling" problem, we'd still have to guess about whether users would want 1) to have the CPN inside the case structure, 2) to call the CPN first and then wire the error out into a case structure or 3) to have a case structure with the error wired through into a CPN called after the specialized code. If we put the CPN inside the case structure, most users would probably still need to drop an additional case structure inside the first to check the error coming out of the CPN, right? So, it doesn't seem like there's a one-size-fits-all solution.

Yes, I had realized the ambiguities just as you describe with combining the Call Parent Method. I think it's simpler to add a Call Parent Method then make the other changes we have been describing. I guess "ideally" I'd want to be able to select a template from the shortcut menu, either from the menu itself or via a pop-up dialog.

Personally, I like the blank case structure implementation, but then I like that template in general and I am really glad it is readily available in the other templates available from the shortcut menu. (Thank you!) I appreciate AQ's comments about error handling (and have pondered the issue myself but not too deeply), though, and realize this may not be the most useful general solution. I happen to like it now but others may not use the template much (readers please comment!) and there may be a better error handling solution. (I'm not averse to adopting a better way!) At the moment I find the blank error strucure the most useful template for my applications so I like to start there....

Link to comment

QUOTE(Paul_at_Lowell @ Oct 15 2007, 11:20 AM)

At the moment I find the blank error strucure the most useful template for my applications so I like to start there....

Just a warning about creating override from New>>VI from Dynamic Dispatch Template... There are certain VI properties (like reentrancy) which are required to match between base implementations and override VIs. I don't know them all off the top of my head, but they are documented in the help. If you've modified any of these in the base implementation and don't modify them in the override, the override VI will be broken. Yes, the Error List will tell you what you need to fix, but that might be kind of a hassle for you. Even worse, though, might be properties that are NOT required to match which you set in the base implementation, but don't think about setting up in the override, even though you intended to have them match in the override VI. These kinds of things might even slip through your testing undetected. I'm not saying you should never create an override by starting with New>>VI from Dynamic Dispatch Template. I just want to raise awareness of a possible gotcha.

Personally, I think it's faster to start with the New>>VI for Override and ctrl-drag to make space. Usually I delete the CPN, sometimes I don't, but starting this way ensures that I won't have to worry about what the front panel looks like (assuming I like how it looked in the parent class) or wiring up the connector pane or having to set anything up in VI Properties.

Link to comment
  • 2 months later...

QUOTE(Robbie Gehbauer @ Oct 15 2007, 12:57 PM)

Personally, I think it's faster to start with the New>>VI for Override and ctrl-drag to make space. Usually I delete the CPN, sometimes I don't, but starting this way ensures that I won't have to worry about what the front panel looks like (assuming I like how it looked in the parent class) or wiring up the connector pane or having to set anything up in VI Properties.

OK, I have tried using the method you describe the last couple months. I am still wishing for a streamlined path (i.e., new override method template) with LVOOP. In fact, it is the number one item on my personal wish list for the next release. The "create space" method requires resizing the window and it is essentially impossible to create space each time such that one doesn't have to move the controllers and indicators around to make them line up vertically with the default case structure I inevitably end up copying into the VI. This is an inconvenience, admittedly, but having a suitable template for override methods is probably the one thing I most miss among the many other nice LVOOP enhancements in 8.5. (I'm pretty excited about LVOOP and I use it all the time.) (The create space method just takes a while for each override method....)

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.