The const Qualifier
Now let's return to the topic of symbolic names for constants. A symbolic name can suggest what the constant represents. Also, if the program uses the constant in several places and you need to change the value, you can just change the single symbol definition. The note about #define statements earlier in this chapter (see the sidebar "Symbolic Constants the Preprocessor Way") promises that C++ has a better way to handle symbolic constants. That way is to use the const keyword to modify a variable declaration and initialization. Suppose, for example, that you want a symbolic constant for the number of months in a year. You enter this line in a program:
const int MONTHS = 12; // Months is symbolic constant for 12
Now you can use MONTHS in a program instead of 12. (A bare 12 in a program might represent the number of inches in a foot or the number of donuts in a dozen, but the name MONTHS tells you what the value 12 represents.) After you initialize a constant such as MONTHS, its value is set. The compiler does not let you subsequently change the value MONTHS. If you try to, for example, Borland C++ gives an error message stating that an lvalue is required. This is the same message you get if you try, say, to assign the value 4 to 3. (An lvalue is a value, such as a variable, that appears on the left side of the assignment operator.) The keyword const is termed a qualifier because it qualifies the meaning of a declaration.
A common practice is to use all uppercase for the name to help remind yourself that MONTHS is a constant. This is by no means a universal convention, but it helps separate the constants from the variables when you read a program. Another convention is to capitalize just the first character in the name. Yet another convention is to begin constant names with the letter k, as in kmonths. And there are yet other conventions. Many organizations have particular coding conventions they expect their programmers to follow.
The general form for creating a constant is this:
const type name = value;
Note that you initialize a const in the declaration. The following sequence is no good:
const int toes; // value of toes undefined at this point toes = 10; // too late!
If you don't provide a value when you declare the constant, it ends up with an unspecified value that you cannot modify.
If your background is in C, you might feel that the #define statement, which is discussed earlier, already does the job adequately. But const is better. For one thing, it lets you specify the type explicitly. Second, you can use C++'s scoping rules to limit the definition to particular functions or files. (Scoping rules describe how widely known a name is to different modules; you'll learn about this in more detail in Chapter 9, "Memory Models and Namespaces.") Third, you can use const with more elaborate types, such as arrays and structures, as discussed in Chapter 4.
If you are coming to C++ from C and you are about to use #define to define a symbolic constant, use const instead.
ANSI C also uses the const qualifier, which it borrows from C++. If you're familiar with the ANSI C version, you should be aware that the C++ version is slightly different. One difference relates to the scope rules, and Chapter 9 covers that point. The other main difference is that in C++ (but not in C), you can use a const value to declare the size of an array. You'll see examples in Chapter 4.