>extern
.Упражнение 2.26. Что из приведенного ниже допустимо? Если что-то недопустимо, то почему?
>(a) const int buf; (b) int cnt = 0;
>(c) const int sz = cnt; (d) ++cnt; ++sz;
Подобно любым другим объектам, с константным объектом можно связать ссылку. Для этого используется ссылка на константу (reference to >const
), т.е. ссылка на объект типа >const
. В отличие от обычной ссылки, ссылку на константу нельзя использовать для изменения объекта, с которым она связана.
>const int ci = 1024;
>const int &r1 = ci; // ok: и ссылка, и основной объект - константы
>r1 = 42; // ошибка: r1 - ссылка на константу
>int &r2 = ci; // ошибка: неконстантная ссылка на константный объект
Поскольку нельзя присвоить значение самой переменной >ci
, ссылка также не должна позволять изменять ее. Поэтому инициализация ссылки >r2
— это ошибка. Если бы эта инициализация была допустима, то ссылку >r2
можно было бы использовать для изменения значения ее основного объекта.
Программисты С++, как правило, используют термин константная ссылка (const reference), однако фактически речь идет о ссылке на константу (reference to const).
С технической точки зрения нет никаких константных ссылок. Ссылка — не объект, поэтому саму ссылку нельзя сделать константой. На самом деле, поскольку нет никакого способа заставить ссылку ссылаться на другой объект, то в некотором смысле все ссылки — константы. То, что ссылка ссылается на константный или неконстантный тип, относится к тому, что при помощи этой ссылки можно сделать, однако привязку самой ссылки изменить нельзя в любом случае.
В разделе 2.1.2 мы обращали ваше внимание на два исключения из правила, согласно которому тип ссылки должен совпадать с типом объекта, на который она ссылается. Первое исключение: мы можем инициализировать ссылку на константу результатом выражения, тип которого может быть преобразован (см. раздел 2.1.2) в тип ссылки. В частности, мы можем связать ссылку на константу с неконстантным объектом, литералом или более общим выражением:
>int i = 42;
>const int &r1 = i; // можно связать ссылку const int& с обычным
> // объектом int
>const int &r2 =42; // ok: r1 - ссылка на константу
>const int &r3 = r1 * 2; // ok: r3 - ссылка на константу
>int &r4 = r * 2; // ошибка: r4 - простая, неконстантная ссылка
Простейший способ понять это различие в правилах инициализации — рассмотреть то, что происходит при связывании ссылки с объектом другого типа:
>double dval = 3.14;
>const int &ri = dval;
Здесь ссылка >ri
ссылается на переменную типа >int
. Операции со ссылкой >ri
будут целочисленными, но переменная >dval
содержит число с плавающей запятой, а не целое число. Чтобы удостовериться в том, что объект, с которым связана ссылка >ri
, имеет тип >int
, компилятор преобразует этот код в нечто следующее: