MyTetra Share
Делитесь знаниями!
Особенности модификатора Const в C++ при работе с указательями и ссылками
22.11.2019
14:28
Автор: Xintrea
Текстовые метки: язык, c++, модификатор, const, указатель, ссылка
Раздел: Компьютер - Программирование - Язык C++

Ключевое слово Const и указатели


Если нужно передать массив в функцию так, чтобы можно было менять элементы массива, пользуются таким синтаксисом:



void show(unsigned char * block)



Однако, если массив просто передается, и его элементы не должны изменяться, правильнее будет использовать модификатор const:



void show(const unsigned char * block)



с модификатором const есть много путанницы. Вопрос: что значит запись "const unsigned char *" - это запрет модификации элементов массива, или запрет модификации указателя на массив? Правильный ответ - запрет модификации элементов массива. Чтобы понять, почему так, нужно знать, что на самом деле, такая запись - это историческое "расширение" синтаксиса C++. В первых версиях стандарта такого синтаксиса предусмотрено не было. Предолагалась только четкая запись в виде:



<Тип> <Модификатор доступа>



и правильная запись (эквивалент вышеприведенной) будет выглядеть так:



void show(unsigned char const * block)



То есть, модификатор доступа const влияет на тип, написанный слева от него, вот и все дела. То есть, данная запись означает, что константным будет тип unsigned char, таким образом неизменными будут оставаться данные массива, а не указатель на массив (ведь звездочка осталась справа). Но потом в стандарт была добавлена возможность написания модификатора доступа в начало определения, и однозначность сразу исчезла. Теперь модификатор доступа const пишется по такому правилу:




1. Модификатор доступа const пишется после типа, и, соответственно, влияет на тип, расположенный слева от него.

2. Но если const написан в начале определения, то он влияет на "короткий" тип справа от него.



"Короткий тип" - это имеется в виду минимально возможное написание типа, которое расположено справа от const. То есть, в нашем примере "const unsigned char * block", минимально возможный тип будет unsigned char без звездочки. Таким образом получаем, что запись вида "const в начале" говорит о невозможности изменить сами данные в массиве, а не невозможность изменить указатель на массив.


Пользуясь правилом, становится понятно, как написать невозможность изменения указателя на массив. Вот так:



void show(unsigned char * const block)



Здесь работает первая часть правила. Можно написать невозможность изменения как данных в массиве, так и указателя на массив:



void show(unsigned char const * const block)



Здесь тоже работает первая часть правила. Но на практике чаще будут встречаться описания с ведущим const (по второму пункту правила):



// Неизменны только данные массива

void show(const unsigned char * block)


// Неизменны и данные массива и указатель

void show(const unsigned char * const block)



Ключевое слово Const и ссылки


В отличие от указателей, ссылки по своей природе обладают таким важным свойством, как невозможность изменения адреса, куда указывает ссылка. Поэтому ссылка инициализируется сразу при создании, и нет возможности задать ей место, куда она должна указывать, где-либо еще в коде. Поэтому никакого смысла в модификаторе, который бы блокировал изменение именно ссылки (а не значения, на которое она указывает) нет.


Поэтому имеет смысл говорить только о синтаксисе параметров функций, который бы блокировал изменение значения, на которое указывает ссылка. И этот синтаксис полностью эквивалентен синтаксису указателей, только вместо звездочки (*) используется амперсанд (&).


Следующие прототипы функций полностью эквивалентны:



void showValue(const double & value)

void showValue(double const & value)



Такая форма записи запрещает изменять значение, на которое указывает ссылка.


Хорошим тоном считается писать модификатор const для ссылок, у которых значение, на которое она указывает, не должно меняться внутри функций.



Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования