home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / std / cplus / 1116 < prev    next >
Encoding:
Internet Message Format  |  1992-08-26  |  4.8 KB

  1. From: pabloh@hpwala.wal.hp.com (Pablo Halpern )
  2. Date: Wed, 26 Aug 1992 18:25:08 GMT
  3. Subject: Re: Expanding enumerators in inheriting classes
  4. Message-ID: <3582@hpwala.wal.hp.com>
  5. Organization: Hewlett-Packard Company
  6. Path: sparky!uunet!elroy.jpl.nasa.gov!sdd.hp.com!hpscdc!hplextra!hpcc05!hpcuhb!hpda!hpwala!pabloh
  7. Newsgroups: comp.std.c++
  8. References: <1992Aug10.200814.12809@ntmtv> <1992Aug11.133926.28840@actrix.gen.nz> <1992Aug11.190816.8623@inmet.camb.inmet.com> <1992Aug12.1
  9. Sender: netnews@hpwala.wal.hp.com
  10. Keywords: inheritance, enumerator
  11. Lines: 104
  12.  
  13. In article <1992Aug17.062809.24177@lth.se>, dag@control.lth.se (Dag Bruck) writes:
  14. |> In an earlier life I seriously doubted that enumerations could be
  15. |> emulated with some other language elements.  That is of course a good
  16. |> reason to try to do it anyway.
  17. |> 
  18. |> Here is some code that uses templates to do something that is similar
  19. |> in spirit to built-in enumerations.  I have deliberately thrown out
  20. |> several safety measures in these classes to give the compiler a chance
  21. |> to produce code with reasonable efficiency.
  22. |> 
  23. |> I have managed to realize some important properties of built-in
  24. |> enumerations:
  25. |> 
  26. |>     1.  Typed symbolic values
  27. |>     2.  Overloading of operators
  28. |>     3.  Similar syntax of usage (not of declaration)
  29. |> 
  30. |> As far as I can tell, there are a few fundamental differences between
  31. |> the template enumeration and the built-in enumeration that we cannot
  32. |> (or want to) get around:
  33. |> 
  34. |>     1.  Template enumerators are not compile-time constants
  35. |>     2.  Template enumerators cannot be used as case labels
  36. |>     3.  There seems to be no good way to restrict the set
  37. |>         of enumerators that belong to an enumeration
  38.  
  39. [ more discussion and code deleted ]
  40.  
  41. This discussion started out being about extending enumerations through
  42. inheritance or an inheritance-like mechanism.  Dag's template-based
  43. approach does this, but is limited in the ways he mentions.  I have another
  44. approach that I have used in practice, and which doesn't require a compiler
  45. that supports templates.  It has none of the flaws Dag mentions, although
  46. it may have different flaws.  One flaw I know of is that it is not type
  47. safe because any enumeration value can be assigned to any enumeration
  48. variable, regardless of whether they are of the same type.  Because of
  49. enumerator's equivalence to int, the same flaw exists in the built-in
  50. enumeration feature of C++.
  51.  
  52. Basically, this scheme involves wrapping enum types in classes.  This has
  53. the benefit of keeping the namespace of enumeration constants disjoint
  54. between different enumeration types.  This system is an idiom; there is no
  55. re-usable class library except for the base class, enumeration.  Therefore,
  56. I must explain my system using an example:
  57.  
  58.   // re-usable base class
  59.   class enumeration
  60.   {
  61.   public:
  62.     // convert to/from int
  63.     operator int() const { return _val; }
  64.     enumeration& operator = (int i) { _val = i; return *this; }
  65.     // Operators ==, !=, <, etc. can be implemented using int conversion
  66.   protected:
  67.     enumeration(int i = 0) { _val = i; }
  68.     int _val;
  69.   };
  70.  
  71.   // This class is created for a communications package
  72.   class modemCommand : public enumeration
  73.   {
  74.   public:
  75.     enum { DIAL, HANGUP, CHANGE_SPEED, _next };
  76.     modemCommand(int i) : enumeration(i) {}
  77.     modemCommand& operator = (int i) { _val = i; return *this; }
  78.   };
  79.  
  80.   // This class is derived years later for a fax package
  81.   class faxModemCommand : public modemCommand
  82.   {
  83.   public:
  84.     // Note: first item starts where base class leaves off
  85.     enum { SET_FAX_MODE = modemCommand::_next, SET_DATA_MODE, SET_VOICE_MODE,
  86.            _next };
  87.     faxModemCommand(int i) : modemCommand(i) {}
  88.     faxModemCommand& operator = (int i) { _val = i; return *this; }
  89.   };
  90.  
  91.   // Some uses of these classes
  92.   enumeration e1;  // illegal: protected constructor
  93.   modemCommand mc1 = modemCommand::DIAL;
  94.   faxModemCommand fc1 = modemCommand::HANGUP;     // Okay
  95.   faxModemCommand fc2 = faxModemCommand::HANGUP; // Same thing.
  96.   modemCommand mc2 = faxModemCommand::SET_FAX_MODE;  // This is legal, but it
  97.                                                      // shouldn't be.
  98.  
  99. Note the use of the _next value for derivation.  Each derived class defines an
  100. enumeration that starts from the _next value of its imediate base class.  Of
  101. course, each class can have additional member variables and functions
  102. associated with it, if you want.  Some run-time type checking could be added,
  103. if you want, by putting range checks in the copy constructors and assignment
  104. operators.
  105.  
  106. -- 
  107.  
  108. - Pablo
  109.  
  110. ------------------------------------------------------------------------
  111. Pablo Halpern             (617) 290-3542
  112. HP Waltham                pabloh@hpwarq.wal.hp.com
  113.  
  114. I am self-employed, so my opinions *do* reflect those of my employer.
  115. However, they may not reflect the opinions of my client.
  116. ------------------------------------------------------------------------
  117.