2.4.3 Top-Level const
As we’ve seen, a pointer is an object that can point to a different object. As a result, we can talk independently about whether a pointer is const and whether the objects to which it can point are const. We use the termtop-level const to indicate that the pointer itself is a const. When a pointer can point to a const object, we refer to that const as a low-level const.
EXERCISES SECTION 2.4.2
Exercise 2.27: Which of the following initializations are legal Explain why.
(a) int i = -1, &r = 0; (b) int *const p2 = &i2;
(c) const int i = -1, &r = 0; (d) const int *const p3 = &i2;
(e) const int *p1 = &i2; (f) const int &const r2;
(g) const int i2 = i, &r = i;
Exercise 2.28: Explain the following definitions. Identify any that are illegal.
(a) int i, *const cp; (b) int *p1, *const p2;
(c) const int ic, &r = ic; (d) const int *const p3;
(e) const int *p;
Exercise 2.29: Uing the variables in the previous exercise, which of the following assignments are legal Explain why.
(a) i = ic; (b) p1 = p3;
(c) p1 = ⁣ (d) p3 = ⁣
(e) p2 = p1; (f) ic = *p3;
More generally, top-level const indicates that an object itself is const. Toplevel const can appear in any object type, i.e., one of the built-in arithmetic types, a class type, or a pointer type. Low-level const appears in the base type of compound types such as pointers or references. Note that pointer types, unlike most other types, can have both top-level and low-level const independently:
- int i = 0;
- int *const p1 = &i;
- const int ci = 42;
- const int *p2 = &ci;
- const int *const p3 = p2;
- const int &r = ci;
The distinction between top-level and low-level matters when we copy an object. When we copy an object, top-level consts are ignored:
- i = ci;
- p2 = p3;
Copying an object doesn’t change the copied object. As a result, it is immaterial whether the object copied from or copied into is const.
On the other hand, low-level const is never ignored. When we copy an object, both objects must have the same low-level const qualification or there must be a conversion between the types of the two objects. In general, we can convert a nonconst to const but not the other way round:
- int *p = p3;
- p2 = p3;
- p2 = &i;
- int &r = ci;
- const int &r2 = i;
p3 has both a top-level and low-level const. When we copy p3, we can ignore its top-level const but not the fact that it points to a const type. Hence, we cannot use p3 to initialize p, which points to a plain (nonconst) int. On the other hand, we can assign p3 to p2. Both pointers have the same (low-level const) type. The fact that p3 is a const pointer (i.e., that it has a top-level const) doesn’t matter.
EXERCISES SECTION 2.4.3
Exercise 2.30: For each of the following declarations indicate whether the object being declared has top-level or low-level const.
- const int v2 = 0; int v1 = v2;
- int *p1 = &v1, &r1 = v1;
- const int *p2 = &v2, *const p3 = &i, &r2 = v2;
Exercise 2.31: Given the declarations in the previous exercise determine whether the following assignments are legal. Explain how the top-level or low-level const applies in each case.
- r1 = v2;
- p1 = p2; p2 = p1;
- p1 = p3; p2 = p3;