Use enum instead of sets of constants

If your constants define a related set, don't use separate const definitions. Instead, make your constants an enumerated type. Remember to document whether the constants may be added to an enumerated type in subsequent releases. Absence of comment implies that the set is unchanging for all eternity.

      const int kRed = 0;
      const int kBlue = 1;
      const int kGreen = 2;
      enum ColorComponent {kRed, kBlue, kGreen};
This causes ColorComponent to become a distinct type that the compiler type-checks. Values of type ColorComponent are automatically converted to int as needed, but integers can't be changed to ColorComponents without a cast. If you need to assign particular numerical values, you can do that too:

      // kBlue and kGreen do not need explicit values because they are 
      //  assigned increasing values automatically. However, it doesn't hurt.
      enum ColorComponent {kRed = -1, kBlue = 0, kGreen = 1};
The type declaration should occur within the scope of a class. Then, references to the constants outside of the class' member functions must be qualified:

      class TColor {
          enum ColorComponent {kRed, kGreen, kBlue};
      foo = TColor::kRed;
NOTE Until recently the enum type name wasn't local to the class; only the actual constants were; the enum type name wasn't qualified. The ANSI base document now states that such type names (indeed all nested type definitions) are local to the class' scope and must be qualified. Thus, the variable foo in the last example was previously declared as a ColorComponent, but must now be a TColor::ColorComponent.

Another language limitation is that compile-time constants other than enum can't have class scope--they must be global. It is illegal to have an initializer for a static class member in the class declaration. However, it is legal to have a static const data member that has a definition elsewhere--such a member is a compile-time constant, but its definition must appear before its use (such as in a header file); otherwise, it isn't usable as a compile-time constant.

Though you can use enum to achieve the same effect, use global constants rather than abusing enum when something must be a compile-time constant. The new C++ namespace feature might ameliorate this problem when it is available in compilers.

[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker