When defining SOMobjects classes, programmers can easily declare and implement new initializers. Classes can have as many initializers as desired, and subclassers can invoke whichever of these they want. When introducing new initializers, developers must adhere to the following rules:
Accordingly, the somDefaultInit initializer introduced by SOMObject takes a somInitCtrl structure as its (only) argument, and returns void. Here is the IDL syntax for this method, as declared in somobj.idl:
void somDefaultInit (inout somInitCtrl ctrl);
When introducing a new initializer, it is also necessary to specify the init modifier in the implementation section. The init modifier is what tells emitters that the new method is actually an initializer, so the method can be properly supported from the language bindings. As described below, this support includes the generation of special initializer stub procedures in the implementation template file, as well as bindings containing ancestor-initialization macros and object constructors that invoke the class implementor's new initializers.
It is a good idea to begin the names of initializer methods with the name of the class (or some other string that can be unique for the class). This is important because all initializers available on a class must be newly introduced by that class (that is, you cannot override initializers - except for somDefaultInit). Using a class-unique name means that subclasses will not be unnecessarily constrained in their choice of initializer names.
Here are two classes that introduce new initializers:
interface Example1 : SOMObject { void Example1_withName (inout somInitCtrl ctrl,in string name); void Example1_withSize (inout somInitCtrl ctrl,in long size); void Example1_withNandS(inout somInitCtrl ctrl,in string name, in long size); implementation { releaseorder: Example1_withName, Example1_withSize, Example1_withNandS; somDefaultInit: override, init; somDestruct: override; Example1_withName: init; Example1_withSize: init; Example1_withNandS: init; }; }; interface Example2 : Example1 { void Example2_withName(inout somInitCtrl ctrl, in string name); void Example2_withSize(inout somInitCtrl ctrl, in long size); implementation { releaseorder: Example2_withName, Example2_withSize; somDefaultInit: override, init; somDestruct: override; Example2_withName: init; Example2_withSize: init; }; };
Here, interface "Example1" declares three new initializers. Notice the use of inout somInitCtrl as the first argument of each initializer, and also note that the init modifier is used in the implementation section. These two things are required to declare initializers. Any number of initializers can be declared by a class. "Example2" declares two initializers.
"Example1" and "Example2" both override the somDefaultInit initializerThis initializer method is introduced by SOMObject and is special for two resons: First, somDefaultInit is the only initializer that can be overridden And, second, SOMobjects arranges that this initializer will always be available on any class (as further explained below).
Historically in the SOMobjects Toolkit, object#initialization methods by default have invoked the somInit method, which class implementors could override to customize initialization as appropriate. SOMobjects continues to support this approach, so that existing code (and class binaries) will execute correctly. However, the somDefaultInit method is now the preferred form of initialization because it offers greatly improved efficiency.
Even if no specialized initialization is needed for a class, you should still override the somDefaultInit method in the interest of efficiency. If you do not override somDefaultInit, then a generic (and therefore less efficient) somDefaultInit method procedure will be used for your class. This generic method procedure first invokes somDefaultInit on the appropriate ancestor classes. Then (for consistency with earlier versions of SOMobjects), it checks to determine if the class overrides somInit and, if so, calls any customized somInit code provided by the class.
When you override somDefaultInit, the emitter's implementation template file will include a stub procedure similar to those used for other initializers, and you can fill it in as appropriate (or simply leave it as is). Default initialization for your class will then run much faster than with the generic method procedure. Examples of initializer stub procedures (and customizations) are given below.
In summary, the initializers available for any class of objects are somDefaultInit (which you should always override) plus any new initializers explicitly declared by the class designer. Thus, "Example1" objects may be initialized using any of four different initializers (the three that are explicitly declared, plus somDefaultInit). Likewise, there are three initializers for the "Example2" objects. Some examples of using initializers are provided below.