14.3 Classes in HLA


14.3 Classes in HLA

HLA's classes provide a good mechanism for creating abstract data types. Fundamentally, a class is little more than a record declaration that allows the definition of non-data fields (e.g., procedures, constants, and macros). The inclusion of other objects in the class definition dramatically expands the capabilities of a class over that of a record. For example, with a class it is now possible to easily define an ADT because classes may include data and methods (procedures) that operate on that data.

The principle way to create an abstract data type in HLA is to declare a class data type. Classes in HLA always appear in the type section and use the following syntax:

 classname : class                << Class declaration section >>           endclass; 

The class declaration section is very similar to the local declaration section for a procedure insofar as it allows const, val, var, and static variable declaration sections. Classes also let you define macros and specify procedure, iterator,[2] and method prototypes (method declarations are legal only in classes). Conspicuously absent from this list is the type declaration section. You cannot declare new types within a class.

A method is a special type of procedure that appears only within a class. A little later you will see the difference between procedures and methods; for now you can treat them as being one and the same. Other than a few subtle details regarding class initialization and the use of pointers to classes, their semantics are identical.[3] Generally, if you don't know whether to use a procedure or method in a class, the safest bet is to use a method.

You do not place procedure/iterator/method code within a class. Instead you simply supply prototypes for these routines. A routine prototype consists of the procedure, iterator, or method reserved word, the routine name, any parameters, and a couple of optional procedure attributes (@use, @returns, and @external). The actual routine definition (i.e., the body of the routine and any local declarations it needs) appears outside the class.

The following example demonstrates a typical class declaration appearing in the type section:

 TYPE      TypicalClass: class           const                TCconst := 5;           val                TCval := 6;           var                TCvar : uns32;           // Private field used only by TCproc.           static                TCstatic : int32;           procedure TCproc( u:uns32 ); @returns( "eax" );           iterator TCiter( i:int32 ); @external;      method TCmethod( c:char ); endclass; 

As you can see, classes are very similar to records in HLA. Indeed, you can think of a record as being a class that only allows var declarations. HLA implements classes in a fashion quite similar to records insofar as it allocates sequential data fields in sequential memory locations. In fact, with only one minor exception, there is almost no difference between a record declaration and a class declaration that only has a var declaration section. Later you'll see exactly how HLA implements classes, but for now you can assume that HLA implements them the same as it does records and you won't be too far off the mark.

You can access the TCvar and TCstatic fields (in the class above) just like a record's fields. You access the const and val fields in a similar manner. If a variable of type TypicalClass has the name obj, you can access the fields of obj as follows:

 mov ( obj.TCconst, eax ); mov( obj.TCval, ebx ); add( obj.TCvar, eax ); add( obj.TCstatic, ebx ); obj.TCproc( 20 );      // Calls the TCproc procedure in TypicalClass. etc. 

If an application program includes the class declaration above, it can create variables using the TypicalClass type and perform operations using the mentioned methods. Unfortunately, the application program can also access the fields of the ADT data type with impunity. For example, if a program created a variable MyClass of type TypicalClass, then it could easily execute instructions like "mov( MyClass.TCvar, eax );" even though this field might be private to the implementation section. Unfortunately, if you are going to allow an application to declare a variable of type TypicalClass, the field names will have to be visible. While there are some tricks we could play with HLA's class definitions to help hide the private fields, the best solution is to thoroughly comment the private fields and then exercise some restraint when accessing the fields of that class. Specifically, this means that ADTs you create using HLA's classes cannot be "pure" ADTs because HLA allows direct access to the data fields. However, with a little discipline, you can simulate a pure ADT by simply electing not to access such fields outside the class's methods, procedures, and iterators.

Prototypes appearing in a class are effectively forward declarations. Like normal forward declarations, all procedures, iterators, and methods you define in a class must have an actual implementation later in the code. Alternately, you may attach the @external option to the end of a procedure, iterator, or method declaration within a class to inform HLA that the actual code appears in a separate module. As a general rule, class declarations appear in header files and represent the interface section of an ADT. The procedure, iterator, and method bodies appear in the implementation section, which is usually a separate source file that you compile separately and link with the modules that use the class.

The following is an example of a sample class procedure implementation:

 procedure TypicalClass.TCproc( u:uns32 ); @nodisplay;      << Local declarations for this procedure >> begin TCproc;      << Code to implement whatever this procedure does >> end TCProc; 

There are several differences between a standard procedure declaration and a class procedure declaration. First, and most obvious, the procedure name includes the class name (e.g., TypicalClass.TCproc). This differentiates this class procedure definition from a regular procedure that just happens to have the name TCproc. Note, however, that you do not have to repeat the class name before the procedure name in the begin and end clauses of the procedure (this is similar to procedures you define in HLA namespaces).

A second difference between class procedures and non-class procedures is not obvious. Some procedure attributes (@use, @external, @returns, @cdecl, @pascal, and @stdcall) are legal only in the prototype declaration appearing within the class while other attributes (@noframe, @nodisplay, @noalignstack, and @align) are legal only within the procedure definition and not within the class. Fortunately, HLA provides helpful error messages if you stick the option in the wrong place, so you don't have to memorize this rule.

If a class routine's prototype does not have the @external option, the compilation unit (that is, the program or unit) containing the class declaration must also contain the routine's definition or HLA will generate an error at the end of the compilation. For small, local classes (i.e., when you're embedding the class declaration and routine definitions in the same compilation unit) the convention is to place the class's procedure, iterator, and method definitions in the source file shortly after the class declaration. For larger systems (i.e., when separately compiling a class's routines), the convention is to place the class declaration in a header file by itself and place all the procedure, iterator, and method definitions in a separate HLA unit and compile them by themselves.

[2]This text does not discuss iterators. See the HLA Reference Manual for details on this type of function.

[3]Note, however, that the difference between procedures and methods makes all the difference in the world to the object-oriented programming paradigm. Hence the inclusion of methods in HLA's class definitions.




The Art of Assembly Language
The Art of Assembly Language
ISBN: 1593272073
EAN: 2147483647
Year: 2005
Pages: 246
Authors: Randall Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net