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