Sunday, June 19, 2011

The Const Keyword

The keyword const is short for “constant” and specifies, or requires, that something remain unchanged. As you’ve seen in various places in this book, and probably in real-world code, there are two different, but related, uses of the const keyword: for marking variables and for marking methods. This section provides a definitive discussion of these two meanings.

const Variables:-
You can use const to “protect” variables by specifying that they cannot be modified. One important use of this keyword is as a replacement for #define to declare constants. This use of const is its most straightforward application. For example, you could declare the constant
PI like this:

const double PI = 3.14159;

You can mark any variable const, including global variables and class data members. You can also use const to specify that parameters to functions or methods should remain unchanged.

const Pointers:-
When a variable contains one or more levels of indirection via a pointer, applying const becomes trickier. Consider the following lines of code:

int* ip;
ip = new int[10];
ip[4] = 5;

Suppose that you decide to apply const to ip. Set aside your doubts about the usefulness of doing so for a moment, and consider what it means. Do you want to prevent the ip variable itself from being changed, or do you want to prevent the values to which it points from being changed? That is, do you want to prevent the second line or the third line in the previous example? In order to prevent the pointed-to value from being modified (as in the third line), you can add the keyword const to the declaration of ip like this:

const int* ip;
ip = new int[10];
ip[4] = 5; // DOES NOT COMPILE!

Now you cannot change the values to which ip points. Alternatively, you can write this:

int const* ip;
ip = new int[10];
ip[4] = 5; // DOES NOT COMPILE!

Putting the const before or after the int makes no difference in its functionality. If you want instead to mark ip itself const (not the values to which it points), you need to write this:

int* const ip = NULL;
ip = new int[10]; // DOES NOT COMPILE!
ip[4] = 5;

Now that ip itself cannot be changed, the compiler requires you to initialize it when you declare it. You can also mark both the pointer and the values to which it points const like this:

int const* const ip = NULL;

An alternative syntax is the following:

const int* const ip = NULL;

Although this syntax might seem confusing, there is actually a very simple rule: the const keyword applies to whatever is directly to its left. Consider this line again:

int const* const ip = NULL;

From left to right, the first const is directly to the right of the word int. Thus, it applies to the int to which ip points. Therefore, it specifies that you cannot change the values to which ip points. The second const is directly to the right of the *. Thus, it applies to the pointer to the int, which is the ip variable. Therefore, it specifies that you cannot change ip (the pointer) itself.

const applies to the level of indirection directly to its left.

The reason this rule becomes confusing is an exception: the first const can go before the variable like this:

const int* const ip = NULL;

This “exceptional” syntax is used much more commonly than the other syntax. You can extend this rule to any number of levels of indirection. For example:

const int * const * const * const ip = NULL;


const Methods:-
you can mark a class method const. That specification prevents the method from modifying any non-mutable data members.

No comments:

Post a Comment