home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / cplus / 11508 < prev    next >
Encoding:
Text File  |  1992-07-25  |  4.3 KB  |  148 lines

  1. Xref: sparky comp.lang.c++:11508 comp.std.c++:949
  2. Newsgroups: comp.lang.c++,comp.std.c++
  3. Path: sparky!uunet!ftpbox!mothost!white!motsrd!news
  4. From: shang@corp.mot.com (David (Lujun) Shang)
  5. Subject: Re: run-time type checking (was: Re: Covariant Types in Derived Classes)
  6. Message-ID: <1992Jul24.234628.21196@cadsun.corp.mot.com>
  7. Sender: news@cadsun.corp.mot.com
  8. Reply-To: shang@corp.mot.com
  9. Organization: Motorola, Inc., Software Research and Development, Rolling Meadows, IL. 60008
  10. References: <1992Jul24.143359.3602@advtech.uswest.com>
  11. Date: Fri, 24 Jul 92 23:46:28 GMT
  12. Lines: 134
  13.  
  14. > >(John MAX Skaller) writes: 
  15. >We design our systems properly in the first place, and then the need
  16. >to downcast never arises, when our thoughts wander in that 
  17. >direction one can be sure we are not thinking virtuously,
  18. >and perhaps the design itself is flawed.
  19. > ....
  20.  
  21. In article <1992Jul24.143359.3602@advtech.uswest.com> glw@io.uswest.com (Glenn  
  22. Williams) replies:
  23. >
  24. > You have stated all this before, and every time you do, you fail to provide
  25. > any examples of how you would design without downcasting. 
  26. > So, as I asked for earlier, let's have an example of a properly
  27. > designed system.
  28. Indeed. Whenever I gave an example that demostrates the necessity of downcast,  
  29. I was always considered to introduce a bad design, but I never get an example  
  30. which is considered good and can solve the specific problem shown by my  
  31. example. So, before blaming the "bad", show the good please.
  32.  
  33. Here, I'd like to use the example given by John's own:
  34.  
  35. > >(John MAX Skaller) writes: 
  36. > >class Animal {
  37. > >    int mate(Animal&);
  38. > >};
  39. > >class Dog : Animal {
  40. > >    int mate (Animal&);
  41. > >};
  42. > >We REALLY want Dog::mate(Dog&), but we can't have it.
  43. >
  44.  
  45. Therefore you need RTTI and downcast, though a little bit too late to check the  
  46. validation within the method body:
  47.  
  48. class Dog : Animal
  49. {     int mate (Animal& a)
  50.       { if (typeof(a) != Dog) return an_error_code;
  51.         ...
  52.       };
  53. }
  54.  
  55. > >This is a flaw in Object Oriented Programming IMHO.
  56.  
  57. No. This is not the flaw of OOP. This the problem of the current C++ or some of  
  58. other specific OO langauges and we need to solve it.
  59.  
  60. > >The solution requires multimethods which are inherently
  61. > >functional.
  62.  
  63. Multimethods can never solve this problem. It would be very absurd to have the  
  64. method "mate" multiplxed. We already know that it is impossible to have "cat  
  65. mate dog", "fish mate bird", why we still want to try to mate these impossible  
  66. conbination?
  67.  
  68. What we need is the covariant specification: to prevent the wrong combination  
  69. by interface:
  70.  
  71. class Dog : Animal
  72. {     int mate (thisclass&)
  73.       {  ...
  74.       };
  75. }
  76.  
  77. Therefore, "cat mate dog" will be prohibited by the comipler. This is much  
  78. better since we can prohibit the error earlier. RTTI is required when we do not  
  79. know the actual type of the animals at compile time:
  80.  
  81. Animal & a1;
  82. Animal & a2;
  83.  
  84. if (typeof(a1)==typeof(a2)) a1.mate(a2);
  85.  
  86. Before you condemn this as a bad design, answer the following question first:
  87.  
  88. Is it resonable to call "mate" through Animal interface?
  89. --If yes, how do you prevent the wrong matches without RTTI?
  90. --If no, why do you introduce the method "mate" in class Animal?
  91.  
  92. Now I give you an example that truely needs multiple dispatch.
  93.  
  94. class Animal
  95. {  Animal * fight (Animal * a)
  96.    {  if (a==0 && this->dead()) retuen 0;  // I use this-> for emphasis
  97.       if (a==0 || a->dead()) return this;
  98.       if (this->dead()) return a;
  99.       if (this->over(a) && a->over(this))
  100.       { this->kill(a);
  101.         a->kill(this);
  102.         retuen 0;
  103.       }
  104.       if (this->over(a))
  105.       { this->kill(a);
  106.         retuen this;
  107.       }
  108.       if (a->over(this))
  109.       { a->kill(this);
  110.         retuen a;
  111.       }
  112.       this->escape();
  113.       a->ascape();
  114.       return 0;
  115.    }
  116. };
  117.  
  118. and we have the following fights:
  119.  
  120. Animal * victor;
  121. ..
  122. victor = wolf.fight (jackal);
  123. victor = lynx.fight (victor);
  124. victor = bull.fight (victor);
  125. ..
  126.  
  127. You'll suprise me if you say, okay, I don't care who is the winner, anyway,  
  128. some animal or none. Then what's the purpose of the above codes? Just for some  
  129. thing unknown, unknown forever?  You can say it is a bad design again, as  
  130. easily as blowing off dust. But be aware, it is an example of your beloved  
  131. multiple dispatch.
  132.  
  133. Now can you see the fact: both homo. (the example is "mate") and het. (the  
  134. example is "fight") data structures need RTTI?
  135.  
  136. David Shang
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.