home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / cplus / 15898 < prev    next >
Encoding:
Text File  |  1992-11-08  |  2.7 KB  |  81 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!rational.com!thor!rmartin
  3. From: rmartin@thor.Rational.COM (Bob Martin)
  4. Subject: Re: Casting to an object of a derived class
  5. Message-ID: <rmartin.721099675@thor>
  6. Sender: news@rational.com
  7. Organization: Rational
  8. References: <VANDER.92Nov2153247@vancouver.stars.flab.Fujitsu.co.jp>
  9. Date: Sat, 7 Nov 1992 01:27:55 GMT
  10. Lines: 69
  11.  
  12. vander@flab.fujitsu.co.jp (Mike van der Velden) writes:
  13.  
  14. |I've got:
  15.  
  16. |    class GenericList {
  17. |    public:
  18. |        void*        next ();
  19. |        //...
  20. |    };
  21.  
  22.  
  23. |I'd like to do this:
  24. |    class MyObject : public GenericList {
  25. |    public:
  26. |        int  i;
  27. |    };
  28.  
  29. |    MyObject obj;
  30.  
  31. |Then I'd like to be able to refer to obj.next().i.  Unfortunately, the
  32. |next() returns a reference to an object of type void (or GenericList,
  33. |if I want), and of course i is not a member of that class.  I need
  34. |next() to return a reference of type MyObject in this case (and other
  35. |objects in other cases).
  36.  
  37. This is one of the difficulties with contravariant return types.  It
  38. would sometimes be very nice if a member function could return a
  39. pointer or reference to the most derived object, rather than to the
  40. base.  However, the language does not support this feature.
  41.  
  42. It will, soon, support covariant return types, but these will require
  43. that each derived class repeat the function declaration with the new
  44. return type.
  45.  
  46. So, in general, there is no way to achieve all your goals.  You are
  47. most likely going to have to put extra member function in each
  48. derivateive of GenericList, which casts the output of next to the
  49. derived type.
  50.  
  51. However, I would like to make another kind of observation.  The
  52. practice of inheriting the "ability to be put on a list" has the
  53. weakness that it precludes your objects from being on more than one
  54. list at a time.  Since each object has only one link, it can be in
  55. only one linked list at a time.  But this is not enforced by your
  56. class, so if you try to put the object on more than one list at the
  57. same time, you will wind up corrupting lists in odd ways.
  58.  
  59. A better approach is to use "carriers" in the linked list.  A carrier
  60. is an object of the form:
  61.  
  62.   class Carrier
  63.   {
  64.     public:
  65.       Carrier* link;
  66.       void* object;
  67.   };
  68.  
  69. When you add an element to a linked list, the list creates a new
  70. carrier, links the carrier into the list, and points the 'object'
  71. pointer to the object you are adding to the list.
  72.  
  73. If you combine this technique with templates, you end up with a very
  74. powerful, general purpose linked list class.
  75.  
  76. --
  77. Robert Martin                        Training courses offered in:
  78. R. C. M. Consulting                       Object Oriented Analysis
  79. 2080 Cranbrook Rd.                        Object Oriented Design
  80. Green Oaks, Il 60048 (708) 918-1004       C++
  81.