home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 14 Text / 14-Text.zip / SOMCLA.ZIP / SOMCLA.TXT
Text File  |  1992-09-23  |  29KB  |  759 lines

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