>(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
верхнего уровня (top-level >const
) используется для обозначения того ключевого слова >const
, которое объявляет константой сам указатель. Когда указатель способен указывать на константный объект, это называется спецификатор >const
нижнего уровня (low-level >const
).
В более общем смысле спецификатор >const
верхнего уровня означает, что объект сам константа. Спецификатор >const
верхнего уровня может присутствовать в любом типе объекта, будь то один из встроенных арифметических типов, тип класса или ссылочный тип. Спецификатор >const
нижнего уровня присутствует в базовом типе составных типов, таких как указатели или ссылки. Обратите внимание, что ссылочные типы, в отличие от большинства других типов, способны иметь спецификаторы >const
как верхнего, так и нижнего уровня, независимо друг от друга.
>int i = 0;
>int *const pi = &i; // нельзя изменить значение pi;
> // const верхнего уровня
>const int ci = 42; // нельзя изменить ci; const верхнего уровня
>const int *p2 = &ci; // нельзя изменить p2; const нижнего уровня
>const int *const p3 = p2; // справа const верхнего уровня, слева нет
>const int &r = ci; // const в ссылочных типах всегда нижнего уровня
>const
верхнего и нижнего уровней проявляется при копировании объекта. При копировании объекта спецификатор >const
верхнего уровня игнорируется.>i = ci; // ok: копирование значения ci; спецификатор const верхнего
> // уровня в ci игнорируется
>p2 = p3; // ok: указываемые типы совпадают; спецификатор const верхнего
> // уровня в p3 игнорируется
Копирование объекта не изменяет копируемый объект. Поэтому несущественно, является ли копируемый или копирующий объект константой.
Спецификатор >const
нижнего уровня, напротив, никогда не игнорируется. При копировании объектов у них обоих должны быть одинаковые спецификаторы >const
нижнего уровня, или должно быть возможно преобразование между типами этих двух объектов. Как правило, преобразование неконстанты в константу возможно, но не наоборот.
>int *p = p3; // ошибка: p3 имеет const нижнего уровня, а p - нет
>p2 = p3; // ok: p2 имеет то же const нижнего уровня, что и p3
>p2 = &i; // ok: преобразование int* в const int* возможно
>int &r = ci; // ошибка: невозможно связать обычную int& с
> //