Система 'const' - одна из действительно грязных функций C ++.Концепция проста: переменные, объявленные с добавлением const, становятся константами и не могут быть изменены программой, но, если их использовать для замены одной из недостающих функций C ++, это ужасносложный и разочаровывающе ограничительный.Следующие попытки объяснить, как используется const и почему он существует.Из сочетаний указателей и const указатель константы на переменную полезен для хранения, которое может быть изменено в значении, но не может быть перемещено в памяти, а указатель (постоянный или иной) полезен для возврата константных строк и массивов из функций, которыеПоскольку они реализованы в виде указателей, в противном случае программа может попытаться изменить и завершиться сбоем.Вместо трудного отслеживания сбоя, попытка изменить неизменяемые значения будет обнаружена во время компиляции.
Например, если функция, которая возвращает фиксированную строку 'Some text', написана как
char *Function1()
{ return “Some text”;}
тогда программа может аварийно завершить работу, если она случайно попытается изменить значение, выполнив
Function1()[1]=’a’;
, тогда как компилятор обнаружит ошибку, если будет написана исходная функция
const char *Function1()
{ return "Some text";}
потому что компилятор будет знать, что значение было неизменным.(Конечно, компилятор теоретически мог бы решить это в любом случае, но C не настолько умен.) Когда подпрограмма или функция вызывается с параметрами, переменные, переданные как параметры, могут быть прочитаны для передачи данных в подпрограмму / функцию, записаннуючтобы передать данные обратно в вызывающую программу или и то, и другое, чтобы сделать оба.Некоторые языки позволяют указывать это напрямую, например, иметь типы параметров «in:», «out:» и «inout:», тогда как в C нужно работать на более низком уровне и указывать метод передачи переменных, выбирая одинэто также допускает желаемое направление передачи данных.
Например, подпрограмма, такая как
void Subroutine1(int Parameter1)
{ printf("%d",Parameter1);}
, принимает параметр, переданный ей по умолчанию на C & C ++, который является копией.Поэтому подпрограмма может считывать значение переменной, переданной ей, но не изменять ее, потому что любые изменения, которые она делает, вносятся только в копию и теряются, когда подпрограмма заканчивается, поэтому
void Subroutine2(int Parameter1)
{ Parameter1=96;}
оставит переменную, которой она былаВызван с неизменным, не установленным в 96.
Добавление символа '&' к имени параметра в C ++ (что было очень запутанным выбором символа, потому что знак '&' перед переменными в других местах в C генерирует указатели!) like вызывает использование самой переменной, а не копии, в качестве параметра в подпрограмме и, следовательно, может быть записано для передачи данных обратно в подпрограмму.Поэтому
void Subroutine3(int &Parameter1)
{ Parameter1=96;}
установит для переменной, с которой она была вызвана, значение 96. Этот метод передачи переменной как самой, а не как копии, называется "ссылкой" в C.
Таким образомпередача переменных была дополнением C ++ к C. Для передачи изменяемой переменной в исходном C использовался довольно сложный метод, использующий указатель на переменную в качестве параметра, а затем изменяющий то, на что он указывал.Например,
void Subroutine4(int *Parameter1)
{ *Parameter1=96;}
работает, но требует, чтобы каждое использование переменной в вызываемой подпрограмме изменялось, и вызывающая подпрограмма изменялась для передачи указателя на переменную, что довольно громоздко.
Нооткуда в этом слово «const»?Ну, есть второе распространенное использование для передачи данных по ссылке или указателю вместо копирования.То есть, когда копирование переменной будет тратить слишком много памяти или займет слишком много времени.Это особенно вероятно для больших составных пользовательских типов переменных («структуры» в C и «классы» в C ++).Так что подпрограмма, объявленная
void Subroutine4(big_structure_type &Parameter1);
, может использовать '&', потому что она собираетсяизменить переданную ему переменную, или это может быть просто для экономии времени копирования, и нет никакого способа узнать, что это, если функция скомпилирована в чужой библиотеке. Это может быть риском, если нужно доверять подпрограмме, чтобы не изменять переменную.
Для решения этой проблемы можно использовать «const» в списке параметров, например
void Subroutine4(big_structure_type const &Parameter1);
, что приведет к тому, что переменная будет передана без копирования, но остановит ее от изменения. Это грязно, потому что он по сути делает метод передачи переменных in-only из метода передачи переменных в обоих направлениях, который сам был создан из метода передачи переменных in-only только для того, чтобы заставить компилятор выполнить некоторую оптимизацию.
В идеале программисту не нужно контролировать эту деталь, определяющую, как именно передаются переменные, просто скажите, в каком направлении идет информация, и оставьте компилятору автоматически ее оптимизировать, но C был разработан для грубого низкоуровневого программирования далеко. менее мощные компьютеры, чем стандартные в наши дни, поэтому программист должен делать это явно.