Что такое const в информатике

Многоликий const

Ключевое слово const — одно из самых многозначных в C++. Правильно использование const позволяет организовать множество проверок ещё на этапе компиляции и избежать многих ошибок из числа тех, которые бывает трудно найти при помощи отладчиков и/или анализа кода.

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

Константы и данные

Самый простой случай — константные данные. Возможно несколько вариантов записи:

Все они правильные и делают одно и тоже — создают переменную, значение которой изменить нельзя.

Константы и указатели

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

Работает (const относится к данным):

Тоже самое и тоже работает:

А вот это уже не работает:

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

то ситуация была бы диаметрально противоположной.

Существует мнемоническое правило, позволяющее легко запомнить, к чему относится const. Надо провести черту через «*», если const слева, то оно относится к значению данных; если справа — к значению указателя.

Ну и конечно, const можно написать дважды:

Константы и аргументы/результаты функций

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

Константы и методы (перегрузка)

А вот с методами есть одна тонкость.

Во-первых, для методов допустимо использование const, применительно к this. Синтаксис таков:

Кроме того, этот const позволяет перегружать методы. Таким образом, вы можете писать оптимизированные варианты методов для константных объектов.

То есть для константного объекта (с x=2) был вызван соответствующий метод.

Осталось только добавить, что если вы планируете использовать const-объекты, то вам надо обязательно реализовать const-методы. Если вы в этом случае не реализуете не-const-методы, то во всех случаях будут молча использоваться const-методы. Одним словом, const лучше использовать там, где это возможно.

И ещё… я собрался в отпуск… возможно, не смогу ответить на комментарии до понедельника-вторника. Не сочтите за невнимание 🙂

Источник

const (C++)

При изменении объявления данных const ключевое слово указывает, что объект или переменная не являются изменяемыми.

Синтаксис

Значения-константы

const Ключевое слово указывает, что значение переменной является константой и сообщает компилятору о том, что программист не сможет его изменить.

В C++ const вместо директивы препроцессора const можно использовать ключевое слово, чтобы определить постоянные значения. Значения, определенные с помощью, const подчиняются проверке типа и могут использоваться вместо константных выражений. В C++ можно указать размер массива с помощью const переменной следующим образом:

В языке C константные значения по умолчанию имеют внешнюю компоновку, поэтому они могут использоваться только в файлах исходного кода. В языке C++ константные значения по умолчанию имеют внутреннюю компоновку, которая позволяет использовать их в файлах заголовков.

const Ключевое слово также можно использовать в объявлениях указателей.

Указатели на данные-константы можно использовать в качестве параметров функций, чтобы функция не могла изменять параметр, переданный посредством указателя.

Для объектов, не объявленных как константы, можно вызывать как константные, так и неконстантные функции-члены. Можно также перегружать функцию-член с помощью const ключевого слова; это позволяет вызывать другую версию функции для постоянных и неконстантных объектов.

Нельзя объявлять конструкторы или деструкторы с const ключевым словом.

Функции-члены-константы

Объявление функции-члена с помощью const ключевого слова указывает, что функция является функцией «только для чтения», которая не изменяет объект, для которого она вызывается. Функция-член константы не может изменять какие-либо нестатические элементы данных или вызывать функции-члены, не являющиеся константами. Чтобы объявить функцию-член константы, поместите const ключевое слово после закрывающей скобки списка аргументов. const Ключевое слово требуется как в объявлении, так и в определении.

Различия констант C и C++

При объявлении переменной, как const в файле исходного кода на языке C, это можно сделать следующим образом:

Затем эту переменную можно использовать в другом модуле следующим образом:

Но чтобы получить такое же поведение в C++, необходимо объявить const переменную как:

Если вы хотите объявить extern переменную в файле исходного кода C++ для использования в файле исходного кода на языке C, используйте:

для предотвращения изменения имени компилятором C++.

Remarks

При использовании списка параметров функции-члена const ключевое слово указывает, что функция не изменяет объект, для которого она вызывается.

Дополнительные сведения о const см. в следующих разделах:

Источник

Так вы думаете, что знаете Const?

Думаете, что вы знаете все правила использования const для С? Подумайте еще раз.

Основы const

Скалярные переменные

Вы знакомы с простым правилом const в С.

const перед hello означает, что во время компиляции происходит проверка того, что hello никогда не меняется.

Кроме того, C не сильно беспокоится о том, где расположен const до тех пор пока он находится перед идентификатором, так что объявления const uint32_t и uint32_t const идентичны:

Скалярные переменные в прототипах

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

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

Массивы

Вы можете указать const для всего массива.

const также может указываться после объявления типа:

Структуры

Обычные структуры

Вы можете указать const для всей структуры.

Если мы попытаемся изменить какой-либо член someStructA :

const внутри структуры

Вы можете указать const для отдельных членов структуры:

Если мы попытаемся изменить какие-либо члены someOtherStructB :

Указатели

const для указателей — вот где начинается веселье.

Один const

Давайте использовать указатель на целое число в качестве примера.

Два const

Давайте добавим ещё один const и посмотрим как пойдут дела.

Ага, у нас получилось сделать и данные, и сам указатель неизменяемыми.

Интерлюдия — объясняем объявления const

Но подождите, дальше — больше!

Это распространенный шаблон для перебора последовательностей данных: переходить к следующему элементу, увеличивая указатель, но не позволяя указателю изменять данные.

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

Три const

Сколько способов мы можем использовать, чтобы добавить const к двойному указателю?

Давайте быстро это проверим.

Какие из этих операций допускаются, исходя из объявления выше?

Только первое присваивание не сработало, потому что, если мы прочитаем наше объявление справа налево:

Что, если мы хотим добавить еще один модификатор const на уровень глубже?

Теперь мы дважды защищены от изменений, потому что, если мы прочитаем наше объявление справа налево:

Что если мы хотим заблокировать все изменения при объявлении двойного указателя?

Что теперь мы (не)можем сделать?

Ничего не работает! Успех!

Дополнительные правила

Хаки приведения типов

Что если вы умны и создали изменяемый указатель на неизменяемое хранилище?

Поскольку это C, вы можете отбросить квалификатор const явным преобразованием типа и избавиться от предупреждения (а также нарушения инициализации const ):

Хаки памяти

Что если структура содержит const члены, но вы измените хранящиеся в ней данные после объявления?

Давайте объявим две структуры, различающиеся только константностью их членов.

Будет ли это работать?

Неа, это не работает, потому что прототип 6 для memcpy выглядит так:

memcpy не позволяет передавать ей неизменяемые указатели в качестве dst аргумента, так как dst изменяется при копировании (а someStructA неизменяема).

Заключение

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

Источник

C++ поддерживает две нотации неизменности:

constexpr функция должна быть достаточно простой, чтобы вычисляться компилятором, а также возвращать вычисленное значение. constexpr функции могут вызываться неконстантыми аргументами в контексте которых не требуются константные выражения.

const

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

Поскольку объекты со спецификаторов const не могут быть изменены, то следующий код будет ошибочным:

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

При использовании указателя задействуются два объекта: сам указатель и объект, на который указывает. Префиксное’ объявление указателя с const делает константным объект, а не указатель. Чтобы объявить как const сам указатель, а не объект, на который он указывает, необходимо поместить const после символа указателя. Например:

Местоположение const относительно базового типа не принципиально, поскольку не существует типа данных const*. Принципиальным является положение const относительно символа *. Поэтому возможны следующие записи:

Первая версия используется для строк, элементы которых не должны быть изменены функцией и возвращает указатель на const, который не позволяет изменять результат. Вторая версия используется для изменяемых строк.

Вы можете назначить адрес неконстантной переменной указателю на константу, потому что это не может нанести никакого вреда. Однако адрес константы нельзя назначить неконстантному указателю, поскольку это позволит изменить значение объекта. Например:

constexpr

Константное выражение является выражением, которое вычисляется во время компиляции. Константные выражения не могут использовать значения и переменные, которые не известны во время компиляции.

Существует множество причин, по которым кому-то может понадобиться именованная константа, а не буква или значение, хранящееся в переменной:

Значение constexpr вычисляется во время выполнения компиляции, и если оно не может быть вычислено, то компилятор выдаст ошибку.

Источник

Константы (Руководство по программированию на C#)

Константы должны инициализироваться сразу после объявления. Пример:

В этом примере константа Months всегда имеет значение 12, и его не может изменить даже сам класс. На самом деле в случае, если компилятор встречает идентификатор константы в исходном коде C# (например, Months ), он подставляет значение литерала непосредственно в создаваемый им промежуточный язык (IL). Поскольку с константой в среде выполнения не связан адрес ни одной переменной, поля const не могут передаваться по ссылке и отображаться в выражении как левостороннее значение.

Будьте внимательны, ссылаясь на постоянные значения, определенные в другом коде, например, в DLL. Если в новой версии DLL для константы определяется новое значение, старое значение литерала хранится в вашей программе вплоть до повторной компиляции для новой версии.

Несколько констант одного типа можно объявить одновременно, например:

Выражение, которое используется для инициализации константы, может ссылаться на другую константу, если не создает циклическую ссылку. Пример:

Константы могут иметь пометку public, private, protected, internal, protected internal или private protected. Эти модификаторы доступа определяют, каким образом пользователи класса смогут получать доступ к константе. Дополнительные сведения см. в разделе Модификаторы доступа.

Спецификация языка C#

Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *