Рубрики
Программирование

C++ — Const и указатели

Не так давно столкнулся с одним интересным вопросом, с которым не пришлось сталкиваться с момента моего начала программирования на плюсах.

Работая с Qt часто встречалась конструкция, когда фактические аргументы функции декларировались следующим образом …(…,const some_type* Name,…), а дальше уже внутри тела функции шла работа с объектом типа some_type и именем Name. Обычно, такая конструкция использовалась для получения данных под дальнейшую обработку. Но, есть один нюанс, которого не касались в университетских курсах по программированию, а также при повторном просмотре книжки Шилдта, я его не нашел.

Допустим есть такой код:
[cpp]

<span style="line-height: 1.5;">const int iA = 5;
</span><span style="line-height: 1.5;">int iB = 1;

iA = iB;//Не будет работать уже на этапе компиляции
iB = iA;//Будет работать, что логично.
//Ведь можно скопировать значение из константы в неконстанту</span>
[/cpp]
Но если в коде будут не int, а int*, то что тогда сможет выполниться?
[cpp]

const int* piA = 5;
int* piB = 1;

piA = piB;//Скомпилируется, выполнится
piB = piA;//Будет ругаться на этапе компиляции на присваивание в из const int* в int*
*piA = *piB;//Будет ругаться на изменение значения константы
*piB = *piA;//Выполнится без вопросов

[/cpp]

Но почему такое необычное поведение? Почему имея const int* мы можем поменять сам указатель, но не значение, которое лежит по адресу из этого указателя?
Ответ кроется в том, что это не постоянный указатель на объект, а это указатель на постоянный объект. Но что делать, если мы хотим, чтобы неизменным остался адрес, а не то, что по нему лежит?
Для этого, нужно перенести const непосредственно между именем типа и именем переменной. Т.е. код будет следующим:
[cpp]

int* const piA = 5;
int* piB = 1;

piA = piB;//Теперь выдаст ошибку, а остальное скомпилируется и выполнится
piB = piA;
*piA = *piB;
*piB = *piA;

[/cpp]