Теперь рассмотрим, что могло бы произойти, будь инициализация позволена, но ссылка ri
не была бы константной. В этом случае мы могли бы присвоить значение по ссылке ri
. Это изменило бы объект, с которым связана ссылка ri
. Этот временный объект имеет тип не dval
. Программист, заставивший ссылку ri
ссылаться на переменную dval
, вероятно, ожидал, что присвоение по ссылке ri
изменит переменную dval
. В конце концов, почему произошло присвоение по ссылке ri
, если не было намерения изменять объект, с которым она связана? Поскольку связь ссылки с временным объектом осуществляет уж конечно не то, что подразумевал программист, язык считает это некорректным.
Важно понимать, что ссылка на константу ограничивает только то, что при помощи этой ссылки можно делать. Привязка ссылки к константному объекту ничего не говорит о том, является ли сам основной объект константой. Поскольку основной объект может оказаться неконстантным, он может быть изменен другими способами:
int i = 42;
int &r1 = i; //
const int &r2 = i; //
//
r1 = 0; //
r2 = 0; //
Привязка ссылки r2
к неконстантной переменной i
типа int
вполне допустима. Но ссылку r2
нельзя использовать для изменения значения переменной i
. Несмотря на это, значение переменной i
вполне можно изменить другим способом, Например, можно присвоить ей значение непосредственно или при помощи другой связанной с ней ссылки, такой как r1
.
const
Подобно ссылкам, вполне возможно определять указатели, которые указывают на объект константного или неконстантного типа. Как и ссылку на константу (см. раздел 2.4.1), const
) невозможно использовать для изменения объекта, на который он указывает. Адрес константного объекта можно хранить только в указателе на константу:
const double pi = 3.14; //
double *ptr = π //
const double *cptr = π //
//
*cptr = 42; //
В разделе 2.3.2 упоминалось о наличии двух исключений из правила, согласно которому типы указателя и объекта, на который он указывает, должны совпадать. Первое исключение — это возможность использования указателя на константу для указания на неконстантный объект:
double dval = 3.14; //
cptr = &dval //
Подобно ссылке на константу, указатель на константу ничего не говорит о том, является ли объект, на который он указывает, константой. Определение указателя как указателя на константу влияет только на то, что с его помощью можно сделать. Не забывайте, что нет никакой гарантии того, что объект, на который указывает указатель на константу, не будет изменяться.
В отличие от ссылок, указатели — это объекты. Следовательно, подобно любым другим объектам, вполне может быть указатель, сам являющийся константой. Как и любой другой константный объект, const
после символа *
. Это означает, что данный указатель является константой, а не обычным указателем на константу.
int errNumb = 0;
int *const curErr = &errNumb // curErr всегда будет указывать на errNumb
const double pi = 3.14159;
const double *const pip = π //
//