home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / s / somcls.zip / SOMCLASS.TXT < prev   
Text File  |  1992-12-02  |  29KB  |  760 lines

  1. CLASS OBJECTS IN SOM
  2. by Nurcan Coskun and Roger Sessions
  3.  
  4. THIS ARTICLE WAS PUBLISHED IN THE PERSONAL SYSTEMS DEVELOPER
  5. AND IS COPYRIGHT BY IBM
  6. -----------------------------------------------------
  7. Note:
  8. 1. Words inside angle brackets should be computer font.
  9. 2. Bold lines are indicated by "<--" in right margin.
  10.  
  11. Author contact information:
  12. Nurcan Coskun AUSVM1(NURCAN) tieline 678-8073
  13. Roger Sessions AUSMV1(SESSIONS) tieline 678-8085
  14. -----------------------------------------------------
  15.  
  16. ABSTRACT
  17. This article continues the discussion of SOM begun in the winter
  18. issue of the Personal Systems Developer.  In this article we look
  19. at one of the advanced programming features of SOM: the class
  20. object.  The class object can be used to retrieve at run time a
  21. great deal of useful information about classes, including the name
  22. of the class and the methods supported.  The class object also
  23. knows how to instantiate objects of a given class.  We give an
  24. overview of the class object, and discuss the concept of metaclass.
  25. A metaclass of a given class is the class of that class's class
  26. object.  We show the two important techniques for changing a
  27. class's metaclass.
  28.  
  29. INTRODUCTION
  30. In the winter issue of the Personal Systems Developer [Sessions and
  31. Coskun, 92], we gave an introduction to the System Object Model
  32. (SOM).  SOM is a new methodology for creating object-oriented class
  33. libraries introduced by IBM in OS/2 2.0.  In our last article we
  34. discussed the basic concepts of object-oriented programming:
  35. developing classes and instantiating objects; deriving new classes
  36. through inheritance; and resolving methods with polymorphism.  We
  37. also discussed the primary goals of SOM: multi-language support
  38. (including both procedural and object-oriented languages); upwardly
  39. compatible binaries; and object-oriented extensions to nonobject-
  40. oriented languages.
  41.  
  42.      In this article we are going to explore an advanced feature of
  43. SOM: the class object.  We assume that you are familiar with the
  44. introductory concepts of our last article.  If you find yourself
  45. getting lost here, you should go back and revisit our winter
  46. article.
  47.  
  48. GOALS OF SOM
  49. SOM is a language neutral mechanism for developing object-oriented
  50. class libraries.  SOM consists of a run-time repository for class
  51. information and a series of language bindings.  Pictorially we can
  52. describe SOM as shown in Figure 1.
  53.  
  54. ................................................................
  55. Figure 1. SOM Run-Time Class Repository and Language Bindings
  56.  
  57. +-+ +-----+ +-------+ +---+ +---------+
  58. |C| |Cobol| |Fortran| |C++| |Smalltalk|
  59. +-+ +-----+ +-------+ +---+ +---------+
  60.  |     |        |       |        |
  61.  V     V        V       V        V  ... etc
  62. +------------------------------------------+
  63. |       SOM Run-Time Class Repository      |
  64. +------------------------------------------+
  65.  |     |        |       |        |  ... etc
  66.  V     V        V       V        V
  67. +-+ +-----+ +-------+ +---+ +---------+
  68. |C| |Cobol| |Fortran| |C++| |Smalltalk|
  69. +-+ +-----+ +-------+ +---+ +---------+
  70. ................................................................
  71.  
  72.      The box in Figure 1 with C pointing to the Run-Time Repository
  73. represents a binding which allows classes to be defined in C and
  74. added to the SOM run-time repository.  The box from the run-time
  75. repository to C is a binding which allows C to use classes from the
  76. repository regardless of the language in which the classes were
  77. originally written.  When we say "use a class", we mean either
  78. instantiating and invoking methods on objects of a class, or
  79. deriving new classes using that class as a base class.
  80.  
  81.      In the current version of OS/2 2.0, we support only the C
  82. language bindings.  The other languages shown in figure 1 are for
  83. illustration only.  This is neither a complete list of languages
  84. under consideration nor a committed list.  We are working with a
  85. wide variety of language suppliers, both internally and externally,
  86. to make this list as complete as possible.
  87.  
  88.      As we discussed in the Winter issue, the C bindings allow
  89. object-oriented programs to be developed much like they are
  90. developed in C++.  However in contrast to C++, SOM allows classes
  91. to be used by a wide variety of languages as new language bindings
  92. become available.  SOM also solves other weaknesses in C++ when it
  93. comes to developing class libraries.  For a good introduction to
  94. C++ and these library issues, see Class Construction in C and C++
  95. [Sessions, 92].
  96.  
  97. CLASSES IN SOM
  98. Lets reconsider a set of classes we first looked at in the winter
  99. issue.  We will start with the <Student> class.  An object of type
  100. <Student> knows how to set up its id and name.  It knows how to
  101. return its ID.  Finally, it knows how to print itself.  The class
  102. definition file for <Student> is shown in Figure 2.
  103.  
  104. ....................................................
  105. Figure 2. <Student> class definition
  106. include <somobj.sc>
  107. class:
  108.   Student;
  109. parent:
  110.   SOMObject;
  111. data:
  112.   char  id[16];      /* student id */
  113.   char  name[32];    /* student name */
  114. methods:
  115.   override  somInit;
  116.   void  setUpStudent(char *id, char *name);
  117.   void  printStudentInfo();
  118.   char  *getStudentType();
  119.   char  *getStudentId();
  120. ....................................................
  121.  
  122.      The class implementation file for <Student> is shown in Figure
  123. 3.  Recall from our last article that most of the class
  124. implementation file is produced automatically by the SOM compiler.
  125. Those lines shown in bold face are the only lines the class
  126. implementor actually needs to write.
  127.  
  128. ................................................................
  129. Figure 3. <Student> class implementation
  130. (Programmer added lines shown in bold type)
  131.  
  132. #define Student_Class_Source
  133. #include "student.ih"
  134.  
  135. SOM_Scope void SOMLINK somInit(Student *somSelf)
  136. {
  137.   StudentData *somThis = StudentGetData(somSelf);
  138.   parent_somInit(somSelf);
  139.   _id[0] = _name[0] = '\0';                          <--
  140. }
  141. SOM_Scope void SOMLINK setUpStudent(Student *somSelf,
  142.     char *id, char *name)
  143. {
  144.   StudentData *somThis = StudentGetData(somSelf);
  145.   strcpy(_id, id);                                   <--
  146.   strcpy(_name, name);                               <--
  147. }
  148. SOM_Scope void   SOMLINK printStudentInfo(Student *somSelf)
  149. {
  150.   StudentData *somThis = StudentGetData(somSelf);
  151.   printf("\n    Id         : %s \n", _id);           <--
  152.   printf("    Name       : %s \n", _name);           <--
  153.   printf("    Type       : %s \n", _getStudentType(somSelf));
  154. }
  155. SOM_Scope char *  SOMLINK getStudentType(Student *somSelf)
  156. {
  157.   StudentData *somThis = StudentGetData(somSelf);
  158.   static char *type = "student";                     <--
  159.   return (type);                                     <--
  160. }
  161. SOM_Scope char *  SOMLINK getStudentId(Student *somSelf)
  162. {
  163.   StudentData *somThis = StudentGetData(somSelf);
  164.   return (_id);                                      <--
  165. }
  166. ................................................................
  167.  
  168.      Given this definition of <Student>, we can derive a new class,
  169. say <GraduateStudent>, which is just like a student, but has
  170. information about a thesis and a degree.  The class definition file
  171. for <GraduateStudent> is shown in Figure 4, and the class
  172. implementation file is shown in Figure 5.
  173.  
  174. ................................................................
  175. Figure 4. <GraduateStudent> class definition file.
  176.  
  177. include "student.sc"
  178. class:
  179.   GraduateStudent;
  180. parent:
  181.   Student, local;
  182. data:
  183.   char  thesis[128];    /* thesis title */
  184.   char  degree[16];     /* graduate degree type */
  185. methods:
  186.   override  somInit;
  187.   override  printStudentInfo;
  188.   override  getStudentType;
  189.   void  setUpGraduateStudent(char *id, char *name,
  190.     char *thesis, char *degree);
  191. ................................................................
  192.  
  193. ................................................................
  194. Figure 5. <GraduateStudent> class implementation file.
  195. (Programmer added lines shown in bold type.)
  196.  
  197. #define GraduateStudent_Class_Source
  198. #include "graduate.ih"
  199.  
  200. SOM_Scope void   SOMLINK somInit(GraduateStudent *somSelf)
  201. {
  202.   GraduateStudentData *somThis =
  203.      GraduateStudentGetData(somSelf);
  204.   parent_somInit(somSelf);
  205.   _thesis[0] = _degree[0] = '\0';                    <--
  206. }
  207. SOM_Scope void   SOMLINK printStudentInfo(
  208.   GraduateStudent *somSelf)
  209. {
  210.   GraduateStudentData *somThis =
  211.     GraduateStudentGetData(somSelf);
  212.   parent_printStudentInfo(somSelf);
  213.   printf("    Thesis     : %s \n", _thesis);         <--
  214.   printf("    Degree     : %s \n", _degree);         <--
  215. }
  216. SOM_Scope char *  SOMLINK getStudentType(
  217.   GraduateStudent *somSelf)
  218. {
  219.   GraduateStudentData *somThis =
  220.     GraduateStudentGetData(somSelf);
  221.   static char *type = "Graduate";                    <--
  222.   return (type);                                     <--
  223. }
  224. SOM_Scope void   SOMLINK setUpGraduateStudent(
  225.   GraduateStudent *somSelf, char *id, char *name,
  226.   char *thesis, char *degree)
  227. {
  228.   GraduateStudentData *somThis =
  229.      GraduateStudentGetData(somSelf);
  230.   _setUpStudent(somSelf,id,name);                    <--
  231.   strcpy(_thesis, thesis);                           <--
  232.   strcpy(_degree, degree);                           <--
  233. }
  234.  
  235. ................................................................
  236.  
  237.      With these two classes defined and implemented, we can write
  238. client code to instantiate and manipulate <Student>s and
  239. <GraduateStudent>s.  The program shown in Figure 6 instantiates two
  240. <Student>s and two <GraduateStudent>s, initializes the objects with
  241. data, and asks the objects to print themselves.
  242.  
  243. .................................................................
  244. Figure 6. Client Program For <Student> and <GraduateStudent>
  245.  
  246. Program:
  247. #include "graduate.h"
  248.  
  249. main()
  250. {
  251.   Student *student1 = StudentNew();
  252.   Student *student2 = StudentNew();
  253.   GraduateStudent *grad1 = GraduateStudentNew();
  254.   GraduateStudent *grad2 = GraduateStudentNew();
  255.  
  256.   _setUpStudent(student1,"120455","Joe Doe");
  257.   _setUpStudent(student2,"103606","Mary Smith");
  258.   _setUpGraduateStudent(grad1,"203230","Janet Brown",
  259.                         "Parser Generators", "M.S.");
  260.   _setUpGraduateStudent(grad2,"240900","Mark Black",
  261.                         "Code Optimization", "Ph.D.");
  262.  
  263.   _printStudentInfo(student1);
  264.   _printStudentInfo(student2);
  265.   _printStudentInfo(grad1);
  266.   _printStudentInfo(grad2);
  267. }
  268.  
  269. Output:
  270.     Id         : 120455
  271.     Name       : Joe Doe
  272.     Type       : student
  273.  
  274.     Id         : 103606
  275.     Name       : Mary Smith
  276.     Type       : student
  277.  
  278.     Id         : 203230
  279.     Name       : Janet Brown
  280.     Type       : Graduate
  281.     Thesis     : Parser Generators
  282.     Degree     : M.S.
  283.  
  284.     Id         : 240900
  285.     Name       : Mark Black
  286.     Type       : Graduate
  287.     Thesis     : Code Optimization
  288.     Degree     : Ph.D.
  289.  
  290. .................................................................
  291.  
  292. CLASS OBJECTS
  293. Every class with at least one instantiated object has exactly one
  294. associated class object.  Every instantiated object maintains a
  295. pointer to its class object which it can return through the method
  296. <somGetClass>.  This method is inherited from <SOMObject>, a class
  297. from which every class is derived, either directly or indirectly.
  298. In the program shown in Figure 6, <student1> and <student2> are
  299. both objects of class <Student>, and therefore both share the same
  300. class object.  Similarly <grad1> and <grad2> are both objects of
  301. class <GraduateStudent>, and therefore both share another class
  302. object, different than the class object shared by <student1> and
  303. <student2>.  This is shown pictorially in Figure 7.
  304.  
  305. ..............................................................
  306. Figure 7. Relationship between objects and class objects
  307. +--------+                                       +-----+
  308. |student1|---> +-------+   +---------------+ <---|grad1|
  309. +--------+     |Student|   |GraduateStudent|     +-----+
  310.                |class  |   |class          |
  311. +--------+     |object |   |object         |     +-----+
  312. |student2|---> +-------+   +---------------+ <---|grad2|
  313. +--------+                                       +-----+
  314. ..............................................................
  315.  
  316.      Another way to access a class object is through the SOM
  317. defined macro <_classname>.  For <Student>, this macro is
  318. <_Student>.  This macro returns a pointer to the appropriate class
  319. object, if it exists, or zero, if it does not exist.  SOM
  320. instantiates the class object the first time an object of its
  321. controlled class is instantiated.  The <_Student> will, therefore,
  322. return 0 if and only if no <Student> objects have yet been
  323. instantiated.
  324.  
  325.      The class object is quite a useful object.  The class of a
  326. class object is either <SOMClass> or, as we will see later, some
  327. class derived from <SOMClass>.  There are a variety of methods
  328. defined for <SOMClass>, and these are all documented in the class
  329. definition file for <SOMClass>, <somcls.sc> and described in the
  330. SOM documentation [SOM].  There are methods which can tell you the
  331. size the class, the parent of the class, whether the class is
  332. derived from some other class, and whether the class supports a
  333. specific method, to name a few.
  334.  
  335.      One of the <SOMClass> methods is <somGetName()>, which returns
  336. a pointer to a character string containing the name of the class
  337. for which this is the class object.  For the <Student> class
  338. object, this string would be "Student".
  339.  
  340.      Another interesting <SOMClass> method is <somNew()>, which
  341. returns a newly instantiated object of the appropriate class.  For
  342. the <Student> class object, the newly instantiated object would be
  343. of the <Student> class.  The method <somNew()> is always invoked to
  344. instantiate new objects.  Many programmers are not aware of this
  345. because they use a macro wrapper of the form <classnameNew>, for
  346. example, <StudentNew()>.  This wrapper first makes sure the
  347. appropriate class object exists, and then passes through the
  348. instantiation request via <somNew()>.
  349.  
  350.      In most cases, we would instantiate objects using the class
  351. instantiation macro, say <StudentNew()>, but there might be cases
  352. when we can access the class object but not the class instantiation
  353. macro.  One such example might be a function which accepts a
  354. pointer to any object, and returns another newly instantiated
  355. object of the same class.  Figure 8 modifies the client program
  356. shown in Figure 6 to make use of the <Student> and
  357. <GraduateStudent> class objects and their <somGetClass()> and
  358. <somNew()> methods.
  359.  
  360. .........................................................
  361. Figure 8. Client Program Using Class Object
  362.  
  363. #include "graduate.h"
  364.  
  365. SOMAny *createObject(SOMAny *object)
  366. {
  367.   return(_somNew(_somGetClass(object)));
  368. }
  369.  
  370. main()
  371. {
  372.   Student *student1 = StudentNew();
  373.   GraduateStudent *grad1 = GraduateStudentNew();
  374.   Student *student2;
  375.   GraduateStudent *grad2;
  376.  
  377.   student2 = createObject(student1);
  378.   grad2 = createObject(grad1);
  379.  
  380.   _setUpStudent(student1,"120455","Joe Doe");
  381.   _setUpStudent(student2,"103606","Mary Smith");
  382.   _setUpGraduateStudent(grad1,"203230","Janet Brown",
  383.                         "Parser Generators", "M.S.");
  384.   _setUpGraduateStudent(grad2,"240900","Mark Black",
  385.                         "Code Optimization", "Ph.D.");
  386.  
  387.   _printStudentInfo(student1);
  388.   _printStudentInfo(student2);
  389.   _printStudentInfo(grad1);
  390.   _printStudentInfo(grad2);
  391. }
  392. .........................................................
  393.  
  394.      Several of the <SOMClass> methods have passthrough methods
  395. defined in <SOMObject>.  In those cases, the actual code for the
  396. passthrough methods just gets the object's class object, and passes
  397. through the call using the appropriate <SOMClass> method.  For
  398. example, the <SOMObject> method <somGetClassName()> passes through
  399. to the <SOMClass> method <somGetName()>.  In this article we will
  400. use either the <SOMObject> methods or the <SOMClass> passthrough,
  401. depending on the point we are making.
  402.  
  403. THE CLASS OF THE CLASS OBJECT
  404. Every object in SOM is associated with a class.  The class of
  405. <student> is <Student>, which we can see from this program:
  406.  
  407. #include "student.h"
  408.  
  409. main()
  410. {
  411.   Student *student = StudentNew();
  412.   printf("student object is of <%s> class\n",
  413.           _somGetClassName(student));
  414. }
  415.  
  416. which gives this output:
  417.  
  418. student object is of <Student> class
  419.  
  420.      The class objects are also associated with a class.  The class
  421. of any class object is by default <SOMClass>.  The class <SOMClass>
  422. is, like all classes, derived from <SOMObject>, and therefore
  423. supports all of the <SOMObject> methods.  We can, for example,
  424. verify the class of the <Student> class object as in the following
  425. program
  426.  
  427. #include "student.h"
  428.  
  429. main()
  430. {
  431.   Student *student = StudentNew();
  432.   SOMClass *studentClassObject;
  433.  
  434.   studentClassObject = _somGetClass(student);
  435.   printf("student class object is of <%s> class\n",
  436.           _somGetClassName(studentClassObject));
  437. }
  438.  
  439. giving this output:
  440.  
  441. student class object is of <SOMClass> class
  442.  
  443.      We use the word metaclass to describe the class of an objects'
  444. class object.  Since the class of the student's class object is
  445. <SOMClass>, we say the metaclass of <Student> is <SOMClass>.  Don't
  446. confuse class with metaclass.  The class of <student> is <Student>.
  447. The metaclass of <student> is <SOMClass>.
  448.  
  449.      We can change the metaclass of a given class by a two stage
  450. process:
  451.  
  452. 1. Derive a new class from SOMClass, either directly or indirectly.
  453. 2. Tell the given class that its class object will be of the new
  454. type through the metaclass directive.
  455.  
  456.      There are at least three reasons one might want to change the
  457. class of a class object.  The first is to add new methods for
  458. initializing new objects.  Such methods are referred to as
  459. constructor methods.  The second is to modify how memory is
  460. allocated for objects.  The third is to keep track of global
  461. information about the class, such as how many objects have been
  462. instantiated.
  463.  
  464.      Lets go through the steps necessary to change the class of the
  465. <Student> class object from <SOMClass> to <StudentFactory>, or, in
  466. other words, changing the metaclass of <student> from <SOMClass> to
  467. <Studentfactory>.  First, we define the <StudentFactory> to be
  468. derived from <SOMClass>.  This class will add one new method to
  469. those found in <SOMClass>.  The new method will be
  470. <countObjects()>.  We will also override the client invoked
  471. <SOMClass> methods <somNew()>, which instantiates a new object.  We
  472. also need to override the <somInit()> method invoked on a newly
  473. instantiated class object, to initialize the count to zero.  The
  474. class definition and implementation files for <StudentFactory> are
  475. shown in Figure 9.
  476. ............................................................
  477. Figure 9: Class Definition and Implementation Files for
  478. <StudentFactory>
  479.  
  480. Class Definition File:
  481. include <somobj.sc>
  482.  
  483. class:
  484.   StudentFactory;
  485. parent:
  486.   SOMClass;
  487. data:
  488.   int count;
  489. methods:
  490.   override somInit;
  491.   override somNew;
  492.   int countObjects();
  493.  
  494. Class Implementation File:
  495. #define StudentFactory_Class_Source
  496. #include "countmet.ih"
  497. SOM_Scope void   SOMLINK somInit(StudentFactory *somSelf)
  498. {
  499.     StudentFactoryData *somThis = StudentFactoryGetData(somSelf);
  500.    parent_somInit(somSelf);
  501.     _count = 0;
  502. }
  503. SOM_Scope SOMAny *  SOMLINK somNew(StudentFactory *somSelf)
  504. {
  505.     StudentFactoryData *somThis = StudentFactoryGetData(somSelf);
  506.    _count ++;
  507.     return (parent_somNew(somSelf));
  508. }
  509. SOM_Scope int   SOMLINK countObjects(StudentFactory *somSelf)
  510. {
  511.     StudentFactoryData *somThis = StudentFactoryGetData(somSelf);
  512.    return (int) _count;
  513. }
  514. ............................................................
  515.  
  516.      We now modify the student class definition files as shown in
  517. Figure 10.
  518.  
  519. ...........................................................
  520. Figure 10: Newly Modified student class definition files
  521. (Modified lines shown in bold face.)
  522. include <somobj.sc>
  523. include "countmet.sc"
  524.  
  525. class:
  526.   Student;
  527. metaclass:                                           <--
  528.   StudentFactory, local;                             <--
  529. parent:
  530.   SOMObject;
  531. data:
  532.   char  id[16];      /* student id */
  533.   char  name[32];    /* student name */
  534. methods:
  535.   override  somInit;
  536.   void  setUpStudent(char *id, char *name);
  537.   void  printStudentInfo();
  538.   char  *getStudentType();
  539.   char  *getStudentId();
  540. ..........................................................
  541.  
  542.      No changes are needed to the class implementation file for
  543. <Student>.
  544.  
  545.      We can now use our new <StudentFactory> object to find out how
  546. many student objects have been instantiated, as shown in this
  547. program:
  548.  
  549. #include "student.h"
  550.  
  551. main()
  552. {
  553.   Student *student1 = StudentNew();
  554.   Student *student2 = StudentNew();
  555.   SOMClass *studentClassObject;
  556.  
  557.   _setUpStudent(student1,"120455","Joe Doe");
  558.   _setUpStudent(student2,"103606","Mary Smith");
  559.  
  560.   studentClassObject = _somGetClass(student1);
  561.   printf("Student count: %d \n",
  562.     _countObjects(studentClassObject));
  563.   printf("student1 class object is of <%s> class\n",
  564.     _somGetClassName(studentClassObject));
  565. }
  566.  
  567. giving this output:
  568.  
  569. Student count: 2
  570. student1 class object is of <StudentFactory> class
  571.  
  572. IMPLIED METACLASS
  573. Given a new class for class objects, we can have any number of
  574. classes associated with the new class object.  For example, instead
  575. of <StudentFactory> we might have used the metaclass name
  576. <CountFactory> to indicate greater generality, and then used this
  577. metaclass whenever we want to keep track of total instantiated
  578. objects.
  579.  
  580.      Often we do not need such generality and we only intend for a
  581. given class object to be associated with one class.  For example,
  582. the only change to the metaclass might be the addition of new
  583. constructor methods which are only applicable to a specific class.
  584. In such cases we can use a slight short cut to redefine the
  585. metaclass.  This short cut is called implied metaclass.  The main
  586. advantage of implied metaclasses is that the class definition file
  587. for the metaclass can be folded into the class definition file for
  588. the class it controls, and similarly for the class implementation
  589. file.
  590.  
  591.      The student implementation file rewritten to use the implied
  592. metaclass is shown in Figure 11.   The student implementation file
  593. rewritten to use the implied metaclass is shown in Figure 12.
  594. .............................................................
  595. Figure 11. Student Class Definition using implied Metaclass
  596. (Changes from original <Student> shown in bold face.)
  597. include <somobj.sc>
  598.  
  599. class:
  600.   Student, classprefix = StudentClass_;            <--
  601. parent:
  602.   SOMObject;
  603. data:
  604.   char  id[16];      /* student id */
  605.   char  name[32];    /* student name */
  606.   int   count, class;                              <--
  607. methods:
  608.   override  somInit;
  609.   void  setUpStudent(char *id, char *name);
  610.   void  printStudentInfo();
  611.   char  *getStudentType();
  612.   char  *getStudentId();
  613.   override somInit, class;                         <--
  614.   override somNew, class;                          <--
  615.   int      countObjects(), class;                  <--
  616. ............................................................
  617.  
  618.      Notice there are two new keywords used to define implied
  619. metaclasses.  The keyword "classprefix" indicates a prefix used to
  620. identify methods associated with the class object.  The keyword
  621. "class" is used to identify data members or methods associated with
  622. the class object.
  623.  
  624. .............................................................
  625. Figure 12. Student Class Implementation using implied Metaclass
  626. (Programmer added lines shown in bold face.)
  627.  
  628. #define Student_Class_Source
  629. #include "student.ih"
  630.  
  631. SOM_Scope void   SOMLINK somInit(Student *somSelf)
  632. {
  633.     StudentData *somThis = StudentGetData(somSelf);
  634.     parent_somInit(somSelf);
  635.     _id[0] = _name[0] = '\0';                          <--
  636. }
  637. /* Other Student Methods, as before, followed by... */
  638. #undef SOM_CurrentClass
  639. #define SOM_CurrentClass SOMMeta
  640.  
  641. SOM_Scope void SOMLINK StudentClass_somInit(
  642.     M_Student *somSelf)
  643. {
  644.     M_StudentData *somThis = M_StudentGetData(somSelf);
  645.     parent_somInit(somSelf);
  646.     _count = 0;                                         <--
  647. }
  648. SOM_Scope SOMAny *SOMLINK StudentClass_somNew(
  649.     M_Student *somSelf)
  650. {
  651.     M_StudentData *somThis = M_StudentGetData(somSelf);
  652.     _count ++;                                           <--
  653.     return (parent_somNew(somSelf));
  654. }
  655. SOM_Scope int SOMLINK StudentClass_countObjects(
  656.     M_Student *somSelf)
  657. {
  658.     M_StudentData *somThis = M_StudentGetData(somSelf);
  659.     return (int) _count;                                  <--
  660. }
  661. ............................................................
  662.  
  663.      Our client program, shown again here, needs no changes:
  664.  
  665. #include "student.h"
  666.  
  667. main()
  668. {
  669.   Student *student1 = StudentNew();
  670.   Student *student2 = StudentNew();
  671.   SOMClass *studentClassObject;
  672.  
  673.   _setUpStudent(student1,"120455","Joe Doe");
  674.   _setUpStudent(student2,"103606","Mary Smith");
  675.  
  676.   studentClassObject = _somGetClass(student1);
  677.   printf("Student count: %d \n",
  678.     _countObjects(studentClassObject));
  679.   printf("student1 class object is of <%s> class\n",
  680.     _somGetClassName(studentClassObject));
  681. }
  682.  
  683. The output, which had looked like:
  684.  
  685. Student count: 2
  686. student1 class object is of <StudentFactory> class
  687.  
  688. now looks like:
  689.  
  690. Student count: 2
  691. student1 class object is of <M_Student> class
  692.  
  693. The difference in output reflects the system assigned name of the
  694. metaclass.
  695.  
  696.  
  697.  
  698. SUMMARY
  699. The class object is an important source of runtime information in
  700. SOM.  Virtually anything that one might want to know about a class
  701. can be found out through one of the class object's methods.  The
  702. class object is itself a fully functional object, like any other
  703. object in SOM.  It has its own class, by default <SOMClass> which
  704. can be modified using any of the normal class modification
  705. techniques including inheritance and polymorphism.
  706.  
  707.      The class object is an important programmer resource.  It is
  708. the source of runtime information about classes and gives the
  709. ability to make runtime decisions about how objects will be
  710. manipulated. Because the class object is a standard SOM object,
  711. instantiated from a standard SOM Class, you have considerable
  712. flexibility to redefine its characteristics as needed.
  713.  
  714. REFERENCES
  715. [Sessions] Class Construction in C and C++: Object-Oriented
  716. Programming Fundamentals, by Roger Sessions.  Prentice Hall,
  717. Englewood Cliffs, New Jersey, 1992.
  718.  
  719. [Sessions and Coskun] Object-Oriented Programming in OS/2 2.0, by
  720. Roger Sessions and Nurcan Coskun.  IBM Personal Systems Developer,
  721. Winter, 1992, 107-120.
  722.  
  723. [SOM] OS/2 2.0 Technical Library System Object Model Guide and
  724. Reference, IBM Doc 10G6309
  725.  
  726. ACKNOWLEDGEMENTS
  727. SOM is the work of many people.  Mike Conner developed the initial
  728. idea and implementation, and continues to lead the overall design
  729. of SOM.  Andy Martin designed the SOM Class Interface Language, and
  730. designed and implemented the class Interface compiler.  Larry Raper
  731. implemented many features of the run time library and porteed SOM
  732. to OS/2.  Larry Loucks provided close technical tracking and was
  733. instrumental in focusing the effort.  Other SOM developers include
  734. Nurcan Coskun, Scott Danforth, Hari Madduri, Roger Sessions, Simon
  735. Nash, and John Wang.  The project is managed by Gerry Ronga.
  736.  
  737. BIOGRAPHIES
  738. Roger Sessions, IBM Corporation, 11400 Burnett Road, Austin, TX
  739. 78758.  He is the author of two books, Reusable Data Structures for
  740. C, and Class Construction in C and C++ - Object-Oriented
  741. Programming Fundamentals, as well as several articles.  He is
  742. working on object-oriented programming environments and previously
  743. worked with high performance relational databases and object-
  744. oriented storage systems.  Mr. Sessions can be contacted at
  745. roger@vnet.ibm.com.  Mr. Sessions has a B.A. from Bard College and
  746. an M.E.S. in Database Systems from the University of Pennsylvania.
  747.  
  748. Nurcan Coskun, IBM Corporation, 11400 Burnet Road, Austin, TX
  749. 78758.  Her expertise is in integrated programming environments,
  750. code generators, incremental compilers, interpreters, language
  751. based editors, symbolic debuggers, application frameworks, and
  752. language design.  She is now working on object-oriented programming
  753. environments and previously worked on the OS/2 Database Manager.
  754. Dr. Coskun can be contacted at nurcan@ausvm1.vnet.ibm.com.  Dr.
  755. Coskun has a B.S. in Industrial Engineering from Middle East
  756. Technical University, an M.S. and a Ph.D. in Computer Science from
  757. the University of Missouri, Rolla.
  758.  
  759.  
  760.