The const Qualifier

C++, like C, supports the const qualifier, which turns variables into constants. In C, the const qualifier specifies that a variable is read-only, except during its one-time initialization. Only through initialization can a program specify a const variable's value. C++ goes a step further and treats such variables as if they are true constant expressions (such as 123). Wherever you can use a constant expression, you can use a const variable. For example:

// The const qualifier

#include <iostream.h>

void main()

{

const int SIZE = 5;

char cs[SIZE];

cout << "The size of cs is " << sizeof cs;

}

This program is illegal in C, because C does not let you use a const variable to specify the size of an array. However, even in C++ you cannot initialize a const variable with anything other than a constant expression. For example, even though SIZE is declared within a function, you cannot initialize it with a parameter of the function. This means you cannot use const to declare an array whose size is determined at run time. To dynamically allocate an array in C++, see Chapter 5, “Classes and Dynamic Memory Allocation.”

You can use const declarations as a replacement for constants defined with the #define directive. C++ lets you place const declarations in header files, which is illegal in C. (If you try doing this in C, the linker generates error messages if the header file is included by more than one module in a program.) Constants declared with const have an advantage over those defined by #define in that they are accessible to a symbolic debugger, making debugging easier.

You can also use const in pointer declarations. In such declarations, the placement of const is significant. For example:

char *const ptr = mybuf; // const pointer

*ptr = 'a'; // Change char that p points to; legal

ptr = yourbuf; // Change pointer; error

This declares ptr as a constant pointer to a string. You can modify the string that ptr points to, but you cannot modify ptr itself by making it point to another string.

However, the following declaration has a different meaning:

const char *ptr = mybuf; // Pointer to const

ptr = yourbuf; // Change pointer; okay

*ptr = 'a'; // Change char that p points to; error

This declares ptr as a pointer to a constant string. You can modify ptr itself so that it points to another string, but you cannot modify the string that ptr points to. In effect, this makes ptr a “read-only” pointer.

You can use const when declaring a function to prevent the function from modifying one of its parameters. Consider the following prototype:

// Node is a large structure

int readonly( const struct Node *nodeptr );

This prototype declares that the readonly function cannot modify the Node structure that its parameter points to. Even if an ordinary pointer is declared inside the function, the parameter is still safeguarded, because you cannot assign a read-only pointer to an ordinary pointer. For example:

int readonly( const struct Node *nodeptr )

{

struct Node *writeptr; // Ordinary pointer

writeptr = nodeptr; // Error - illegal assignment

}

If such an assignment were legal, the Node structure could be modified through writeptr.