Next: , Previous: R*-Tree, Up: GEOMLIB

5.4 Objective programming

5.4.1 Introduction

GEOMLIB uses principles of object-oriented programming to simplify hierarchy and common attributes of curve types. And because VRR is written in pure C language, the objective environment with hierarchy of classes had to be emulated.

Class is a type with defined virtual methods and data fields. Each class has its unique identification number (ID) and a table with pointers to virtual methods (VMT). Class can have one class as an ancestor. All virtual methods of ancestors are derived to descendant class and can be found at the same index of its VMT. Descendant class can replace derived pointer to virtual method or define new virtual methods. VMT also contains some useful information as class ID, instance size, class name and pointer to ancestor class VMT. Each class defines the format of its instances. The ancestor instance structure is substructure of all its descendants. The class must be directly or indirectly derived from a special class o.

Instance of a given class is an allocated structure with corresponding format. Structure contains header with class ID (used to determine pointer to VMT) and space to store instance data. There remain 3 bytes (to align the structure), that may be used by derived classed.

5.4.2 Definition of a new class

Each class xyz must define two structures:

struct geom_xyz
Instance structure. Contains ancestor instance structure as the header.
struct geom_xyz_class
Table of virtual methods. Must contain ancestor VMT structure as the header. There is one global variable geom_xyz_class of that type.

Typical example of class xyz definition, which is descendant of base class o:

     /* definition of instance structure */
     struct geom_xyz {
       struct geom_o o; /* ancestor data */
       int var; /* new data, can be used by any xyz descendants */
     /* used to define new virtual methods in VMT structure */
     #define geom_xyz_VMT geom_o_VMT \
       void (*func)(struct geom_xyz *self);
     /* used to replace derived or initialize
        new pointers to virtual methods in VMT */
     #define geom_xyz_INIT geom_o_INIT \
       .func = &geom_xyz_func,
     /* structures definition (should be in .h file) */
     GEOM_CLASS_HEAD(xyz, o);
     void geom_xyz_func(struct geom_xyz *self)
       /* ... virtual method implementation */
     /* global variables definition (should be in .c file) */
     void main() {
       /* ... */
       /* VMT initialization, unique class ID is generated */
       /* instances of xyz class can be created from now */

5.4.3 Initialization and destruction

Each instance must be initialized before a call to virtual method. During the initialization, class ID is set and the rest of the structure is filled by zeros. Some classes need to initialize additional data in the cleared structure before most methods can work. Functions, that modify the instance from the cleared stated to the valid one, are sometimes called constructors.

The cleanup is done by the virtual destructor defined in class o. This method should destroy all internal structures such as additionally allocated memory.


     /* memory allocation for a new instance */
     struct geom_abc a;
     /* instance initialization */
     geom_instance_init(&a, GEOM_CLASS(abc));
     /* now, instance data are filled by zeros */
     /* ... */
     /* call to virtual destructor */

5.4.4 Virtual methods

Entries in the instance VMT can be accessed by the macro GEOM_INSTANCE_VMT(instance, class, entry). This macro reads the class ID from instance header, looks to table of initialized classes to retrieve address of the incident VMT and then returns the desired entry. Instance must be derived from the given class in the macro parameter and that class must contain the given entry in its VMT.


     struct geom_abc a;
     /* ... */
     /* call to virtual method */
     GEOM_INSTANCE_VMT(&a, abc, func)(&a);

5.4.5 Class hierarchy

Class hierarchy.