A note scribed by Jude Gao from book Effective C++.
Suppose we want to define a global constant such as
LIMIT = 1000.
Don't use preprocessor macro to define global constants
It is a bad practice to use the preprocessor macro to define this global constant, namely,
#define LIMIT 1000.
That is because the name
LIMITmay not get entered into the symbol table. This can be confusing if you get an error during compilation involving the use of the constant, because the error message may refer to
LIMIT, particularly when
LIMITwas defined in a header file you did not write.
Use a global constant instead
Define a constant as such
const int 1000. It is perfectly fine with this approach. However, when you define a constant variable that is of pointer type. The variable needs to be both low-level as well as high-level constant.
Low-level constant concerns the underlying object pointed by the pointer variable, where as High-level constant concerns the pointer variable.
Hence, if we want to define a global constant pointer to an
int, it is insufficient to just define it as
const int *LIMIT = &value;, in which case
LIMIT is not high-level constant. We must remember to define it as constant in both senses:
How to define a class-specific constants
Since we do not want to have a copy of the constant for each instance of the class, we would like to make the constant
static like this:
static const int LIMIT = 1000; is just a declaration, not a definition, so we must provide its definition elsewhere. That is commonly placed inside the
.cpp implementation file. What this is saying is we should add the following line to our code to make our program compilable:
Notice how we do not put
static in the definition. Even though this constant does not seem to have been initialized, its initial value is provided in the declaration.
In contrast to non-constant static variable of a class, we cannot provide any in-class initializer to a static member, so this is compilable:
In order to make it work, we first remove the in-class initializer, i.e.
=1000, and provide a similar definition as in the constant case like
int MyClass::LIMIT = 1000; Since this is a constant, you may leave it as uninitialized as such
We can define a class-specific constant by defining an
enum, not an
enum class, in the class. Here is an example:
We can refer to our "constant" inside just by
WORK_HOURS_PER_WEEK like we would do normally.
Put altogether In the following is a comprehensive example that illustrates these different complications as one defines a class-specific constant or non-constant variables.