ZBasic Language Reference
108
ZBasic Microcontrollers
It should be noted that, although frequently done, it is not necessary to define a default constructor. If you
dont define a default constructor, the compiler will automatically supply one for you that performs only the
fundamental initialization. A constructor that has one or more parameters, all of which have default
values specified, is effectively a default constructor.
One last issue that must be kept in mind when writing the code for a constructor is that, for objects
defined at the module level, the constructor code will be executed before any tasks have been created.
Because of this, you must avoid using any ZBasic System Library routines that rely on the multi-tasking
system being initialized. In particular, the subroutines Sleep(), Delay() and related subroutines must not
be used in a constructor for an object that might be defined at the object level. One way to work around
this limitation is to add a special initialization method to the class that can be called from Main() to perform
initialization that requires the multi-tasking system to be up and running. Another alternative for situations
where a delay is needed, is to add a simple delay method to the class that effects a delay based on the
changing value of Register.RTCTick.
4.5 Object Destruction Issues
When an object reaches the end of its lifetime, i.e. it goes out of scope, it may need to be cleaned up.
For example, if one or more data members are allocated string types, the memory allocated for the string
store (if any) needs to be freed. The ZBasic compiler generates code that correctly deallocates string
members of objects just as it does for individual string variables and structure members that are allocated
string types.
Beyond that automatic cleanup activity, you may need to perform additional cleanup operations at the
end of an objects life. For example, if your object acquires other resources that need to be released, e.g.
a semaphore or memory allocated using System.Alloc(), you need to handle these operations
yourself by writing an optional class method called a destructor. A class may have at most one destructor
which is a parameterless subroutine with the special name _Destroy. In the code for your destructor
you only need to handle the data members that arent automatically handled by the compiler. For
example, you neednt be concerned with string deallocation because that is handled automatically. The
automatically generated cleanup code is executed after the code in your destructor executes.
4.6 Object Assignment Issues
A third optional method, known as an assignment constructor, may be defined to ensure that the
assignment of one object to another (necessarily of the same type) is carried out properly. An
assignment constructor is a subroutine with the special name _Assign() that takes a single ByVal
parameter with the same type as the class. For most classes, it isnt necessary to define an assignment
constructor because the ZBasic compiler correctly handles object assignment. For data members that
are allocated strings, the compiler generates code that frees of the destination object members existing
string and then creates a copy of the source object members string. For data members that are objects,
the compiler generates code that invokes the objects assignment constructor or, if it has none, the
default assignment process for that object. The same strategy is employed for data members that are
structures having allocated string members. However, for all other data members the compiler generates
code that performs a simple byte-wise copy.
If your class has data members that have special requirements, e.g. a data member that is an address of
a block of memory allocated with System.Alloc(), youll need to write your own specialized
assignment constructor. It is important to note that if you do provide an assignment constructor, you are
responsible for handling every data member of the class, not just those that require special treatment. An
example of an assignment constructor for the MyTime class is shown below. In this case, the explicit
assignment constructor is superfluous since it does no more than the default assignment process does. If
an assignment constructor is not needed, it is advisable not to create one because it introduces a
possible source of problems if new data members are added to the class and the assignment constructor
is not updated to handle the new members.
|