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

  1. Path: sparky!uunet!news.centerline.com!matt
  2. From: matt@centerline.com (Matt Landau)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Multiple Inheritance - Necessary?
  5. Date: 20 Nov 1992 20:55:38 GMT
  6. Organization: CenterLine Software, Inc.
  7. Lines: 66
  8. Message-ID: <1ejjcaINN1m5@armory.centerline.com>
  9. References: <By17An.4uH@usenet.ucs.indiana.edu>
  10. NNTP-Posting-Host: 140.239.1.32
  11. Keywords: c++ inheritance
  12.  
  13. In <By17An.4uH@usenet.ucs.indiana.edu> ezachris@iroquois.ucs.indiana.edu writes:
  14. >A friend of mine who programs in Objective-C argues that multiple  
  15. >inheritance is unnecessary and complicated. 
  16. >
  17. >My Objective-C friend would make a new object "Pencil-with-eraser" that  
  18. >would declare two objects inside it.
  19. >
  20. >     PENCIL-WITH-ERASER
  21. >        Eraser TheEraser(...);
  22. >        Pencil ThePencil(...);
  23. >
  24. >I think this sounds like hogwash. What do you think?
  25.  
  26. There are basically two ways you can combine the features of existing 
  27. classes:  composition and inheritance.  Your friend's example above is 
  28. an example where combining classes by composition works perfectly well, 
  29. as long as you don't mind the overhead of having to reimplement many 
  30. member functions of both Pencil and Eraser in your new composed class, 
  31. delegating them back to the component parts.
  32.  
  33. There are other uses of MI for which composition just doesn't provide
  34. the right kind of abstraction.  Consider a class "Collection" that lets
  35. you insert, remove, and search for elements.  Objects that are part of
  36. a collection must have certain attributes that comprise "collectability";
  37. in C++ these attributes are often expressed as virtual member functions
  38. used by the Collection class itself when manipulating members of the
  39. collection.  
  40.  
  41. One approach to building such a system involves declaring an abstract 
  42. base class which we might call Collectable, whose purpose is to declare 
  43. the required virtual functions.  In fact, it would declare that as pure 
  44. virtuals, so that derived classes are forced to provide an implementation 
  45. for each of them.
  46.  
  47. To create a collection of pencils, one would want a class that combined 
  48. the attributes of a pencil with the characteristic of collectability; in
  49. C++, one could express this using multiple inheritance:
  50.  
  51.     class CollectablePencil : public Pencil, public Collectable
  52.     {
  53.       public:
  54.         CollectablePencil(args) : Pencil(args) { }
  55.         virtual ~CollectablePencil(void);
  56.  
  57.         ... implement Collectable's pure virtuals ...
  58.     };
  59.  
  60. Now CollectablePencil can be used in any context where Pencil can be
  61. used, *and* can become an element of a Collection.  Similarly, to build
  62. a herd of elephants, one might start with:
  63.  
  64.     class Elephant : public Pachyderm, public Collectable 
  65.     {
  66.         ...
  67.     };
  68.  
  69. I'm not saying this is the BEST way to deal with collections, but absent
  70. templates (which most compilers are just starting to support), it is an
  71. adequate way, and it's used right now by a number of widely available class
  72. libraries.  It also happens to be a technique that really *requires* MI,
  73. and cannot be done with composition instead.
  74.  
  75. Personally, I find C++'s version of multiple inheritance overcomplicated,
  76. confusing, and extremely fragile - basically more trouble than it's worth.
  77. In my own programming, I try not to use it for anything *except* this sort
  78. of attribute-based mixins.
  79.