home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / cplus / 16778 < prev    next >
Encoding:
Text File  |  1992-11-23  |  5.9 KB  |  155 lines

  1. Path: sparky!uunet!usc!zaphod.mps.ohio-state.edu!uwm.edu!cs.utexas.edu!tamsun.tamu.edu!sumani
  2. From: sumani@cs.tamu.edu (Suman K Inala)
  3. Newsgroups: comp.lang.c++
  4. Subject: Query: object interactions
  5. Date: 23 Nov 1992 18:13:32 GMT
  6. Organization: Texas A&M University, College Station
  7. Lines: 141
  8. Sender: pinky@tamu.edu (The Man Behind The Curtain)
  9. Message-ID: <1er70cINN2d3@tamsun.tamu.edu>
  10. NNTP-Posting-Host: photon.tamu.edu
  11. Summary: non-existent member functions & more
  12. Keywords: objects interactions
  13.  
  14. I am having problems trying to implement objects which can interact
  15. with each other in a wide variety of ways.  Basically, I would
  16. like for one object to be able to call any method for any arbitrary
  17. object, even if that method doesn't exist (in which case it does
  18. nothing) without having to have a base class with a thousand
  19. virtual functions.
  20.  
  21. First, let me try to explain it in code:
  22.  
  23. #include <iostream.h>
  24.  
  25. class X {
  26.     char x;
  27. public:
  28.     X() { x = 'x'; }
  29.     void xvalue(void) { cout << x; }  // xvalue() always says 'x'
  30. };
  31.  
  32. class Y {
  33.     char y;
  34. public:
  35.     Y() { y = 'y'; }
  36.     void yvalue(void) { cout << y; } // yvalue() always says 'y'
  37. };
  38.  
  39. int main(void) {
  40.     X x;
  41.     Y y;
  42.     void *ptr = &x;                 // ptr to object x of class X
  43.  
  44.     cout << "-----------\n";
  45.  
  46.     x.xvalue();     // says 'x'
  47.     y.yvalue();     // says 'y'
  48. //    y->xvalue();    //  Compile error--as it should
  49. //    x->yvalue();    //  Compile error--as it should
  50.  
  51.     ((X *) ptr)->xvalue();  // Prints 'x' as it should
  52.     ((Y *) ptr)->yvalue();  // Prints x!  Not what I want...
  53.                             // Though I understand why it does this
  54.                     // This is asking for a crash
  55.  
  56.                 // What I would like for it to do instead
  57.                 // is nothing, since ptr doesn't have
  58.                 // the member function xvalue(); or better
  59.                 // yet, to call some default function
  60.  
  61. /* 
  62. I could do a virtual function, cast or declare ptr
  63. to be of the base class, and call the value() but
  64. that is not what I want to do.  I have to be able
  65. to handle class Z which does not have a the virtual function value()
  66. To have all objects of class Object is acceptable
  67. but they can't have all the same member functions...
  68. Otherwise I end up with just an atrocious amount of
  69. virtual functions in the base class
  70. */
  71.     return 0;
  72. }
  73.  
  74. Let me try to explain in plain words.  Say we have an object key.
  75. When we use the key, we select one of many possible objects to use
  76. it on, like for instance, a door, a bear, a feather, etc.  These
  77. objects are mostly very different, but any of them can be selected.
  78. We want to call (*if it exists*) the member function unlock() of
  79. the selected object.  If the member function does not exist, have
  80. it do nothing or perhaps say 'Nothing happens.'
  81.  
  82. One solution would be to derive all of these objects from the
  83. same base class and define a virtual function for each of the verbs for
  84. all possible objects which could be used.  However, if we have
  85. 1000 objects each with its own verb (a key can unlock, a hammer can
  86. hit, a knife can slice, a furnace can heat, a pencil can mark,
  87. a shredder can grind..) we end up having a base class with each of
  88. these verbs as a virtual function... Surely there is a more elegant
  89. solution.  We don't want class Bear to have a virtual function
  90. unlock() do we?
  91.  
  92. (The C++ example would perhaps have been better if I had derived
  93. X & Y from W, inheriting the member function value... And then
  94. tried to call value from class Z, which perhaps has a common
  95. ancestor with W, but does not have the member function value().)
  96.  
  97. Maybe one way to put this is - 
  98. if for ptr p there exists member function value()
  99.      p->value(); 
  100. else 
  101.     say 'Nothing happens.';
  102.  
  103. Some other questions: let's say we use the key on the door.  The
  104. door will only unlock if the key is blue.  Is there any way
  105. to determine automatically what object called it, or must the
  106. this ptr for key be passed manually?  In addition, since not all
  107. keys will have the getcolor() method, how would this work?  If
  108. the member function does not exist, then the door object would
  109. like to know that, and take the appropriate action (most likely
  110. say 'I don't open for non-blue keys.')
  111.  
  112. I am using Borland C++ 3.1.  I am thinking of using the CLASSLIB
  113. library supplied by them, which the next question is kind of
  114. specific to.
  115.  
  116. Let us say that the key does have a getcolor() method, but
  117. it returns 'red' instead.  I would like the door to cause the
  118. key and everything attached to it to become glued to the door, being
  119. unable to move, or perhaps become 20% heavier.  Would I have to
  120. encode a 'naive physics' into each object which could interact
  121. with the door?  Using the CLASSLIB library, can an object know what
  122. object contains it (w/o me changing the original class?)  What
  123. if the key is in a bag, and I say to a particular instantiation of key
  124. moveto(chest);  can the key copy itself to the chest (of course)
  125. and then delete itself from the bag in a safe manner?  It should
  126. not simply delete the this ptr because the bag will not know 
  127. that it has been deleted and will become confused.  How is this
  128. done then?
  129.  
  130. Last question:  let's say I need to send some objects over some
  131. line to another machine.  The objects to be send are within a
  132. well-constrained set of classes, ie. each machine knows that
  133. any object sent will only be a an object of class X, Y, or Z,
  134. though with different attributes of course.  One way to do
  135. it would be through a giant switch function, but that seems
  136. arbitrary and not the OO way.  Each time a new class would
  137. be added, changes would have to be made to the switch statement.
  138. Would sending them via a stream be portable across machines?
  139. What are the mechanics behind this?  (ie. a byte or word signifying
  140. what class the object belongs to, and then the data members?
  141.  
  142. That's it; I'd really appreciate some help or comments why certain
  143. things can or can not be done.
  144.  
  145. --
  146. Till next time,                \o/   \o/
  147.                                 V \o/ V     email:pinky@tamu.edu
  148. <>  Sam  Inala  <>                 V
  149.  
  150. --
  151. Till next time,                \o/   \o/
  152.                                 V \o/ V     email:pinky@tamu.edu
  153. <>  Sam  Inala  <>                 V
  154.  
  155.