Как уже упоминалось в разделе 2.3.3, проще всего понять эти объявления, читая их справа налево. В данном случае ближе всего к имени curErr расположен спецификатор const, означая, что сам объект curErr будет константным. Тип этого объекта формирует остальная часть оператора объявления. Следующий символ оператора объявления, *, означает, что curErr — это константный указатель. И наконец, объявление завершает базовый тип, означая, что curErr — это константный указатель на объект типа int. Аналогично pip — это константный указатель на объект типа const double.
Тот факт, что указатель сам является константой, ничто не говорит о том, можем ли мы использовать указатель для изменения основного объекта. Возможность изменения объекта полностью зависит от типа, на который указывает указатель. Например, pip — это константный указатель на константу. Ни значение объекта, на который указывает указатель pip, ни хранящийся в нем адрес не могут быть изменены. С другой стороны, указатель curErr имеет простой, неконстантный тип int. Указатель curErr можно использовать для изменения значения переменной errNumb:
*pip = 2.72; //
//
//
if (*curErr) {
errorHandler();
*curErr = 0; //
//
}
Упражнение 2.27. Какие из следующих инициализаций допустимы? Объясните почему.
(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;
Упражнение 2.28. Объясните следующие определения. Какие из них недопустимы?
(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;
Упражнение 2.29. С учетом переменных из предыдущих упражнений, какие из следующих присвоений допустимы? Объясните почему.
(a) i = ic; (b) pi = p3;
(с) pi = (d) p3 =
(e) p2 = pi; (f) ic = *p3;
const верхнего уровня
Как уже упоминалось, указатель — это объект, способный указывать на другой объект. В результате можно сразу сказать, является ли указатель сам константой и являются ли константой объекты, на которые он может указывать. Термин const верхнего уровняconst) используется для обозначения того ключевого слова const, которое объявляет константой сам указатель. Когда указатель способен указывать на константный объект, это называется const нижнего уровняconst).
В более общем смысле спецификатор const верхнего уровня означает, что объект сам константа. Спецификатор const верхнего уровня может присутствовать в любом типе объекта, будь то один из встроенных арифметических типов, тип класса или ссылочный тип. Спецификатор const нижнего уровня присутствует в базовом типе составных типов, таких как указатели или ссылки. Обратите внимание, что ссылочные типы, в отличие от большинства других типов, способны иметь спецификаторы const как верхнего, так и нижнего уровня, независимо друг от друга.
int i = 0;
int *const pi = &i //
//
const int ci = 42; //
const int *p2 = &ci //
const int *const p3 = p2; //
const int &r = ci; //
const верхнего и нижнего уровней проявляется при копировании объекта. При копировании объекта спецификатор const верхнего уровня игнорируется.
i = ci; //