121 of 208
ZBasic Language Reference 113 ZX Microcontroller Family 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) Call b1.ShowWeight() Call b1._Destroy() Call System.Free(addr) End Sub Another use for a based object is to be able to treat a base class object as if it were a derived object. Here again, it is your responsibility to ensure that such treatment is appropriate. The compiler will not issue any error messages or warnings about incompatible classes. As an example, consider the subroutine below. Sub IdentifyObject(ByVal obj as A) Call obj.Identify() ' Define an object based on the object passed Dim objB as B Based obj.DataAddress Call objB.ShowWeight()