LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Daklu

Class constructors

Status: Declined

Any idea that has received less than 8 kudos within 8 years after posting will be automatically declined.

I'm finding that often my classes have some sort of dynamic private data that needs to be initialized before the object will work correctly.  (Queues, User Events, etc.)  Currently I have to implement some sort of initialization vi that the class user must call every time an object is created.  If the user forgets to do this Labview raises an invalid refnum error.  There are workarounds such as wrapping the class in a .lvlib, using class factories, or checking the queue refnum with every class sub vi.  However, they are workarounds that require extra coding and add complexity.

 

I'd like to have the ability to define a private class constructor that fires behind the scenes every time an object constant or control returns the default value during execution.  With this ability I can be certain the object's dynamic resources have been allocated correctly and it simplifies the api for class users.

18 Comments
Intaris
Proven Zealot

@AQ, would preventing a BD constant not be a prerequisite anyway?

 

Unless each single (base LVOOP) object had a private field "initialised?" which whenever the values are being accessed would either

 

a) pass back the already-initialised values or

b) call a defined constructor function and then do a)

c) pass back the default values if the constructor is not defined

AristosQueue (NI)
NI Employee (retired)

> would preventing a BD constant not be a prerequisite anyway?

 

Yes, it would. And as I said, it is only one of the items that needs to be prevented. The "already initialized" field tactic doesn't work if you allow "make current value default" or have USRs.

Intaris
Proven Zealot

Sounds like a whole lot of work then (and debugging!)

Nate_Moehring
Active Participant

What if you required every class to define a "Default Constructor".  This is a method that gets called to initialize the object data without any parameters.  This method gets called in the background as daklu suggested any time a class is auto-vivified, such as the conditions you listed like running a top level VI that contains a class input in the connector pane.  In this case, the default constructor executes and provides the necessary initialization to make the thing run.

 

In addition to this, the class can define N number of  "Parameterized Constructors", which can be placed on the diagram in lue of a class constant.  Because these methods have been defined as specialized constructors, the default constructor doesn't need to run.  Or, maybe it always runs first, followed by a parameterized constructor.

 

But I do like the idea of having a checkbox in the class properties to say "require constructor", which would disallow dropping a class constant on a diagram on a diagram UNLESS they have a default constructor defined.  The default constructor would not be able to return an error unless it did so by throwing an application exception (different topic).

Nate Moehring

SDG
AristosQueue (NI)
NI Employee (retired)

Nate: Would that include no constants on the diagrams of the class' own VIs? How are you going to write the constructors? How about the descendant VIs? The constructors would need to take an object input in order to allow the children to be initialized. So now you're back to having methods and the only thing you've changed from what we have today is banned block diagram constants of the class on non-class diagrams, which means that your constructors have to be wired with controls, which means you've changed nothing from what we have today except that the compiler can no longer do constant folding to improve performance. And you've really made it annoying to write factory functions (i.e., given an enum, return a different child class value for each value of the enum) since those all have to be controls on the panel. 

 

I hate to keep throwing water on this idea, but I've spent years trying to make this work to no avail, so I've got a counterargument ready for a wide range of suggestions.

Daklu
Active Participant

Nate,

 

I trust AQ knows what he's talking about when he says he hasn't been able to find an acceptable way to support constructors in Labview.  The general consensus on LAVA is (as near as I can tell) to write your own constructors and use them instead of a class constant.  Initially I resisted doing that since it seems to go against the grain of G programming, but I've been doing this for a while now and am mostly happy with how it works.  I give all my classes, regardless of whether or not they have private data that needs initialization, a creator method with a class output terminal and use that instead of the class constant.  (I still use the class constant for strictly type information, such as when downcasting a class wire.)

 

Yes, it does feel a little unnatural at first and classes often won't work correctly when new LVOOP users try to call methods on a class constant, but in the long run I believe it provides more flexibility and a cleaner implementation than built-in constructors.  The hardest part is getting out of the habit of dropping constants directly on the block diagram.

 

-Dave

Nate_Moehring
Active Participant

I agree with you Daklu, I don't drop class constants on diagrams unless I have to, I never have, because I believe that all classes should have either an Initialize or Create method (or some other factory incarnation) for creating objects.  Because of this, I was seconding your motion on the "constructor in the background" concept, or at least asking for a feature similar to the current DVR restriction features in the class inheritance properties to restrict which diagrams can have class constants on them for anything other than connector pane and type casting purposes.

Nate Moehring

SDG
Darren
Proven Zealot
Status changed to: Declined

Any idea that has received less than 8 kudos within 8 years after posting will be automatically declined.