home *** CD-ROM | disk | FTP | other *** search
- From: pabloh@hpwala.wal.hp.com (Pablo Halpern )
- Date: Wed, 26 Aug 1992 18:25:08 GMT
- Subject: Re: Expanding enumerators in inheriting classes
- Message-ID: <3582@hpwala.wal.hp.com>
- Organization: Hewlett-Packard Company
- Path: sparky!uunet!elroy.jpl.nasa.gov!sdd.hp.com!hpscdc!hplextra!hpcc05!hpcuhb!hpda!hpwala!pabloh
- Newsgroups: comp.std.c++
- References: <1992Aug10.200814.12809@ntmtv> <1992Aug11.133926.28840@actrix.gen.nz> <1992Aug11.190816.8623@inmet.camb.inmet.com> <1992Aug12.1
- Sender: netnews@hpwala.wal.hp.com
- Keywords: inheritance, enumerator
- Lines: 104
-
- In article <1992Aug17.062809.24177@lth.se>, dag@control.lth.se (Dag Bruck) writes:
- |> In an earlier life I seriously doubted that enumerations could be
- |> emulated with some other language elements. That is of course a good
- |> reason to try to do it anyway.
- |>
- |> Here is some code that uses templates to do something that is similar
- |> in spirit to built-in enumerations. I have deliberately thrown out
- |> several safety measures in these classes to give the compiler a chance
- |> to produce code with reasonable efficiency.
- |>
- |> I have managed to realize some important properties of built-in
- |> enumerations:
- |>
- |> 1. Typed symbolic values
- |> 2. Overloading of operators
- |> 3. Similar syntax of usage (not of declaration)
- |>
- |> As far as I can tell, there are a few fundamental differences between
- |> the template enumeration and the built-in enumeration that we cannot
- |> (or want to) get around:
- |>
- |> 1. Template enumerators are not compile-time constants
- |> 2. Template enumerators cannot be used as case labels
- |> 3. There seems to be no good way to restrict the set
- |> of enumerators that belong to an enumeration
-
- [ more discussion and code deleted ]
-
- This discussion started out being about extending enumerations through
- inheritance or an inheritance-like mechanism. Dag's template-based
- approach does this, but is limited in the ways he mentions. I have another
- approach that I have used in practice, and which doesn't require a compiler
- that supports templates. It has none of the flaws Dag mentions, although
- it may have different flaws. One flaw I know of is that it is not type
- safe because any enumeration value can be assigned to any enumeration
- variable, regardless of whether they are of the same type. Because of
- enumerator's equivalence to int, the same flaw exists in the built-in
- enumeration feature of C++.
-
- Basically, this scheme involves wrapping enum types in classes. This has
- the benefit of keeping the namespace of enumeration constants disjoint
- between different enumeration types. This system is an idiom; there is no
- re-usable class library except for the base class, enumeration. Therefore,
- I must explain my system using an example:
-
- // re-usable base class
- class enumeration
- {
- public:
- // convert to/from int
- operator int() const { return _val; }
- enumeration& operator = (int i) { _val = i; return *this; }
- // Operators ==, !=, <, etc. can be implemented using int conversion
- protected:
- enumeration(int i = 0) { _val = i; }
- int _val;
- };
-
- // This class is created for a communications package
- class modemCommand : public enumeration
- {
- public:
- enum { DIAL, HANGUP, CHANGE_SPEED, _next };
- modemCommand(int i) : enumeration(i) {}
- modemCommand& operator = (int i) { _val = i; return *this; }
- };
-
- // This class is derived years later for a fax package
- class faxModemCommand : public modemCommand
- {
- public:
- // Note: first item starts where base class leaves off
- enum { SET_FAX_MODE = modemCommand::_next, SET_DATA_MODE, SET_VOICE_MODE,
- _next };
- faxModemCommand(int i) : modemCommand(i) {}
- faxModemCommand& operator = (int i) { _val = i; return *this; }
- };
-
- // Some uses of these classes
- enumeration e1; // illegal: protected constructor
- modemCommand mc1 = modemCommand::DIAL;
- faxModemCommand fc1 = modemCommand::HANGUP; // Okay
- faxModemCommand fc2 = faxModemCommand::HANGUP; // Same thing.
- modemCommand mc2 = faxModemCommand::SET_FAX_MODE; // This is legal, but it
- // shouldn't be.
-
- Note the use of the _next value for derivation. Each derived class defines an
- enumeration that starts from the _next value of its imediate base class. Of
- course, each class can have additional member variables and functions
- associated with it, if you want. Some run-time type checking could be added,
- if you want, by putting range checks in the copy constructors and assignment
- operators.
-
- --
-
- - Pablo
-
- ------------------------------------------------------------------------
- Pablo Halpern (617) 290-3542
- HP Waltham pabloh@hpwarq.wal.hp.com
-
- I am self-employed, so my opinions *do* reflect those of my employer.
- However, they may not reflect the opinions of my client.
- ------------------------------------------------------------------------
-