May 14, 2010, 8:10 p.m.
posted by nogood
Item 7. Const Pointers and Pointers to ConstIn casual conversation, C++ programmers will often say "const pointer" when they really mean "pointer to const." That's unfortunate, because these are two different concepts. T *pt = new T; // ptr to T const T *pct = pt; // ptr to const T T *const cpt = pt; // const ptr to T Before you start tossing const qualifiers into your pointer declarations, you first have to decide what it is that you want to be const: the pointer, the object to which you're pointing, or both. In the declaration of pct, the pointer is not const, but the object it points to is considered to be const; that is, the const qualifier modifies the T base type, not the * pointer modifier. In the case of cpt, we're declaring a constant pointer to a non-constant object; the const qualifier modifies the * pointer modifier, not the T base type. To further confuse the syntactic issues surrounding pointers and const, the order of the declaration specifiers (that is, everything in the pointer declaration that occurs before the first * modifier) is immaterial. For instance, the following two declarations declare variables of exactly the same type: const T *p1; // ptr to const T T const *p2; // also ptr to const T The first form is more traditional, but many C++ experts now recommend the second form. The reasoning is that the second form is less prone to misunderstanding because the declaration can be read backward, as in "pointer to constant T." It doesn't really matter which form we use as long as we're consistent. Be careful, however, of the common error of confusing a declaration of a const pointer with that of a pointer to const. T const *p3; // ptr to const T *const p4 = pt; // const ptr to non-const It's possible, of course, to declare a const pointer to a const. const T *const cpct1 = pt; // everything is const T const *const cpct2 = cpct1; // same type Note that it's often simpler to use a reference in preference to a const pointer: const T &rct = *pt; // rather than const T *const T &rt = *pt; // rather than T *const Notice in some of the previous examples that we were able to convert a pointer to non-const into a pointer to const. For example, we were able to initialize pct (of type const T *) with the value of pt (of type T *). The reason this is legal is that, speaking nontechnically, nothing bad can happen. Consider what happens when the address of a non-const object is copied to a pointer to const, as shown in Figure. A pointer to const may refer to a non-const object.
The pointer to const pct is pointing to a non-const T, but that won't cause any harm. In fact, it's common to refer to non-constant objects with pointers (or references) to const: void aFunc( const T *arg1, const T &arg2 ); //... T *a = new T; T b; aFunc( a, b ); When we call aFunc, we initialize arg1 with a and arg2 with b. We are not claiming thereby that a points to a const object or that b is a const; we are claiming that they will be treated as if they were const within aFunc, whether or not they actually are. Very useful. The reverse conversion, from pointer to const to pointer to non-const, is not legal because it would be dangerous, as illustrated in Figure. A pointer to non-const may not refer to a const object.
In this case, pct may actually be pointing to an object that was defined to be const. If we could convert a pointer to const to a pointer to non-const, then pt could be used to change the value of acT.
const T acT;
pct = &acT;
pt = pct; // error, fortunately
*pt = aT; // attempt to change const object!
The C++ standard tells us that such an assignment will have undefined results; we don't know precisely what will happen, but whatever it is won't be good. Of course, we can use a cast to perform the conversion explicitly.
pt = const_cast<T *>(pct); // not an error, but inadvisable
*pt = aT; // attempt to change const object!
However, the behavior of the assignment is still undefined if pt refers to an object that, like acT, was declared to be const (see New Cast Operators [9, 29]). |
- Comment

