Using NewClass

The C and C++ usage bindings for a SOM class also provide static linkage to a <className>NewClass function that can be used to create the class object. This can be useful if the class object is needed before its instances are created.

For example, the following C code uses the function HelloNewClass to create the "Hello" class object. The arguments to this function are defined by the usage bindings, and indicate the version of the class implementation that is assumed by the bindings. (For more detail on creation of classes, see the later section, "Creating a class object.") Once the class object has been created, the example invokes the method somGetInstanceSize on this class to determine the size of a "Hello" object, uses SOMMalloc to allocate storage, and then uses the HelloRenew macro to create ten instances of the "Hello" class:

   #include <hello.h>
   main()
   {
   SOMClass helloCls; /*  A pointer for the Hello class object */
   Hello objA[10];    /*  an array of Hello instances */
   unsigned char *buffer;
   int i;
   int size;

   /* create the Hello class object:  */
   helloCls =  HelloNewClass(Hello_MajorVersion, Hello_MinorVersion);

   /* get the amount of space needed for a Hello instance:
    * (somGetInstanceSize is a method provided by SOM.) */
   size =  _somGetInstanceSize(helloCls);
   size = ((size+3)/4)*4;  /* round up to doubleword multiple */

   /* allocate the total space needed for ten instances: */
   buffer =  SOMMalloc(10*size);

   /* convert the space into ten separate Hello instances: */
   for (i=0; i<10; i++)
       objA[i] = HelloRenew(buffer+i*size);
   ...
   ...
   /* Uninitialize the objects and free them */
   for (i=0; i<10; i++)
     _somDestruct(objA[i],0,0);
   SOMFree(buffer);
   }

When an object created with the <className>Renew macro is no longer needed, its storage must be freed using the dual to whatever method was originally used to allocate the storage. Two method pairs are typical:

Note: In the somDestruct method call above, the first zero indicates that memory should not be freed by the class of the object (that is, the programmer will do it explicitly). The second zero indicates that the class of the object is responsible for overall control of object uninitialization. For further discussion, see Section 5.5, "Initializing and Uninitializing Objects," in Chapter 5, "Implementing Classes in SOM."

For C++ programmers with usage bindings, instances of a class <className> can be created with a new operator provided by the usage bindings of each SOM class. The new operator automatically creates the class object for <className>, as well as its ancestor classes and metaclass, if they do not yet exist. After verifying the existence of the desired class object, the new operator then invokes the somNewNoInit method on the class. This allocates memory and creates a new instance of the class, but it does not initialize the new object. Initialization of the new object is then performed using one of the C++ constructors defined by the usage bindings. (For further discussion, see Section 5.5 "Initializing and Uninitializing Objects," in Chapter 5, "Implementing Classes in SOM.") Two variations of the new operator require no arguments. When either is used, the C++ usage bindings provide a default constructor that invokes the somDefaultInit method on the new object. Thus, a new object initialized by somDefaultInit would be created using either of the forms:

new <className> new< classname > ( )

For example:

   obj = new Hello;
   obj1 = new Hello();

For convenience, pointers to SOM objects created using the newoperator can be freed using the delete operator, just as for normal C++ objects (or, the somFree method could be used):

  delete obj;
  obj1->somFree;

When previously allocated space will be used to hold a new object, C++ programmers should use the somRenew method, described below. C++ bindings do not provide a macro for this purpose.

somNew and somRenew: C and C++ programmers, as well programmers using other languages, can create instances of a class using the SOM methods somNew and somRenew, invoked on the class object. As discussed and illustrated above for the C bindings, the class object must first be created using the <className>NewClass procedure (or, perhaps, using the somFindClass method-see the section "Using class objects," to follow later in this chapter).

The somNew method invoked on the class object creates a new instance of the class, initializes the object using somDefaultInit, and then returns a pointer to the new object. For instance, the following C example creates a new object of the "Hello" class.

   #include <hello.h>
   main()
   {
     SOMClass helloCls;   /* a pointer to the Hello class */
     Hello obj;           /* a pointer to an Hello instance */
     /* create the Hello class  */
     helloCls = HelloNewClass(Hello_MajorVersion, Hello_MinorVersion);
     obj = _somNew(helloCls); /* create the Hello instance */
   }

An object created using the somNew method should be freed by invoking the somFree method on it after the client program is finished using the object.

The somRenew method invoked on the class object creates a new instance of a class using the given space, rather than allocating new space for the object. The method converts the given space into an instance of the class, initializes the new object using somDefaultInit, and then returns a pointer to it. The argument to somRenew must point to a block of storage large enough to hold the new instance. The method somGetInstanceSize can be used to determine the amount of memory required. For example, the following C++ code creates ten instances of the "Hello" class:

   #include <hello.xh>
   #include <somcls.xh>
   main()
   {
     SOMClass *helloCls; // a pointer to the Hello class
     Hello *objA[10]  //  an array of Hello instance pointers
     unsigned char *buffer;
     int i;
     int size;

    // create the Hello class object
    helloCls =  HelloNewClass(Hello_MajorVersion, Hello_MinorVersion);

    // get the amount of space needed for a Hello instance:
    size = helloCls-> somGetInstanceSize();
    size = ((size+3)/4)*4;  // round up to doubleword multiple

    // allocate the total space needed for ten instances
    buffer =  SOMMalloc(10*size);

    // convert the space into ten separate Hello objects
    for (i=0; i<10; i++)
       objA[i] = helloCls-> somRenew(buffer+i*size);

    // Uninitialize the objects and free them
    for (i=0; i<10; i++)
       objA[i]-> somDestruct(0,0);
    SOMFree(buffer);
   }

The somNew and somRenew methods are useful for creating instances of a class when the header file for the class is not included in the client program at compile time. (The name of the class might be specified by user input, for example.) However, the <className>New macro (for C) and the new operator (for C++) can only be used for classes whose header file is included in the client program at compile time.

Objects created using the somRenew method should be freed by the client program that allocated it, using the dual to whatever allocation approach was initially used. If the somFree method is not appropriate (because the method somNew was not initially used), then, before memory is freed, the object should be explicitly deinitialized by invoking the somDestruct method on it. (The somFree method calls the somDestruct method. Refer to the previous C example for Renew for an explanation of the arguments to somDestruct.)


[Back: Using Renew]
[Next: Invoking methods on objects]