Start Back Next End
  
ZBasic Language Reference
117
ZBasic Microcontrollers
4.15 Using the Const Attribute for Methods
Earlier in this chapter, it was stated that an object may be passed to a subroutine or function ByRef or
ByVal.  If it is passed ByVal, the object instance is considered to be “read-only” within the receiving
procedure.  As such, the procedure has read access to the public data members of the object but it is not
allowed to modify those data members.  Also, the receiving procedure may not pass the object ByRef to
any other procedure or method.  Additionally, in order to invoke a method of the object, that method must
be declared to be “constant”, meaning that it isn’t allowed to modify the object or pass the object by
reference to another method or procedure.  
To define a class method as constant, add the keyword Const following the closing parenthesis of the
parameter list.  Optionally, for methods that are functions, you may instead place the Const keyword
after the function’s return type.  An example is shown below using a previously defined method.
Sub Identify() Const
Call MyObject::Identify()
Debug.Print "I'm an A, size="; m_size
End Sub
Of course, since the method above invokes the base class method of the same name, the latter method
must also have the Const attribute.  In summary, a Const method may invoke only other Const
methods and may not modify any data members or any data members of the base class.
4.16 Based Objects, Reference Objects
It may be useful in some situations to define an object at a specific memory address.  For example, you
may want to allocate some memory using System.Alloc() to hold an object.  Or, you may wish to
define an object that occupies previously allocated space, such as a pre-defined buffer.  In either event,
the desired effect can be achieved by defining an object based at a given address.  Consider the example
below that uses the class B defined in Section 4.11.
Dim buf(1 to 20) as Byte
Sub Main()
Dim b1 as B Based buf.DataAddress
Call b1._Create(5, B::Blue, 25)
Call b1.ShowWeight()
Call b1._Destroy()
End Sub
There are several important aspects of this example that should be clearly understood.  Firstly, when you
create a based object you are responsible for all aspects of its management.  You must ensure that
sufficient space for the object exists at the address at which you base the object.  The example above is
poorly coded because the buffer may, in fact, be too small for the object.  The example could be improved
by replacing the upper bound of the buffer with SizeOf(B).  Secondly, you must explicitly invoke the
constructor for the object before using any of its methods or data members because, prior to the
constructor invocation, the object content is completely undefined.  Note that explicit constructor
invocation is disallowed for non-based objects but is (usually) required for based objects.  Also, you are
also responsible for invoking the object destructor (if necessary).  Failure to do so may lead to memory
“leaks”, i.e. allocated memory blocks that are not properly freed.
A second example, below, illustrates using a based object with allocated memory.  Other than the means
by which the space for the object is acquired, the issues are identical to those of the previous example.
Sub Main()
Dim addr as UnsignedInteger
addr = System.Alloc(SizeOf(B))
Dim b1 as B Based addr
Call b1._Create(5, B::Blue, 25)
Previous page Top Next page