Article View: comp.std.c++
Article #182Re: Expanding enumerators in inheriting classes
From: Pablo Halpern
Date: Wed, 26 Aug 1992 18:25
Date: Wed, 26 Aug 1992 18:25
104 lines
5056 bytes
5056 bytes
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.
------------------------------------------------------------------------
Technical Details
Message-ID:
<3582@hpwala.wal.hp.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!sdd.hp.com!hpscdc!hplextra!hpcc05!hpcuhb!hpda!hpwala!pablohReferences:
<1992Aug10.200814.12809@ntmtv> <1992Aug11.133926.28840@actrix.gen.nz> <1992Aug11.190816.8623@inmet.camb.inmet.com> <1992Aug12.1Show Full Headers
Complete Article Headers
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: arc1-ca.pugleaf.net!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