Выражение освобождения

Автор: manager Воскресенье, Март 23rd, 2008 Нет комментариев

Рубрика: C++. Бархатный путь

ВыражениеОсвобождения ::= [::] delete ВыражениеПриведения
::= [::] delete [] ВыражениеПриведения

Это выражение не имеет определённого значения. А значит и о типе выражения мало что можно сказать определённого. Возможно, что оно является выражением типа void. Именно так обозначается специальный тип, который называется также пустым типом. Операция delete работает с динамической памятью. Она способна прочитать скрытую дополнительную информацию о ранее размещённом в динамической памяти с помощью операции new объекте. Поэтому операция delete требует всего одного операнда указателя на объект.
Последствия выполнения операции delete над указателем непредсказуемы и ужасны, если он ссылается на объект, который ранее не был размещён с помощью операции new. Гарантируется безопасность действия операции delete над нулевым указателем. Для удаления массивов используется специальный вариант операции с квадратными скобками. Удаление констант считается ошибкой. Она фиксируется на стадии трансляции. Позже мы обсудим назначение разделителя в выражениях освобождения и размещения ‘::’.

Постфиксное выражение

Постфиксное выражение определяется на основе первичного выражения. Соответствующее множество БНФ включает множество разнообразных альтернатив.

ПостфиксноеВыражение ::= ПервичноеВыражение
::= ПостфиксноеВыражение [Выражение]
::= ПостфиксноеВыражение ([СписокВыражений])
::= ПостфиксноеВыражение.Имя
::= ПостфиксноеВыражение->Имя
::= ПостфиксноеВыражение++
::= ПостфиксноеВыражение-
СписокВыражений ::= ВыражениеПрисваивания
::= СписокВыражений, ВыражениеПрисваивания

Первичное выражение является частным случаем постфиксного выражения. Вторым в списке возможных альтернатив постфиксных выражений является БНФ, представляющая различные варианты выражений индексации. Это выражение строится из двух выражений — постфиксного (первичного) выражения, за которым следует ещё одно выражение (второй операнд операции индексации), заключённое в квадратные скобки. Обычно первое выражение представляет указатель на объект типа X (пока неважно, какого типа объект), второе выражение является выражением интегрального типа. Это выражение называется индексом.

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

Выражения явного преобразования типа (в функциональной форме) являются ещё одним вариантом постфиксного выражения. Это выражение начинается с имени простого типа (простой тип — не обязательно основной). В круглых скобках заключается список выражений (второй операнд операции преобразования), на основе которого формируется значение типа, заданного первым элементом выражения. Выражение явного преобразования может содержать пустой список значений. В этом случае результатом выполнения подобной операции также оказывается значение (неважно какое) заданного простого типа. Здесь важен именно тип значения. Само же значение зависит от разных обстоятельств. Оно вообще может оказаться неопределённым, а может определяться в ходе выполнения программы.
Следующие две БНФ представляют схемы выражений доступа к члену класса. Они будут рассмотрены позже.

Наконец, последняя пара БНФ представляет постфиксные выражения увеличения и уменьшения. Эти выражения представляют собой сочетания символов (именно символов!) операций с выражениями-операндами. Операнды выражений инкремента и декремента обязаны быть модифицируемым l-выражениями.

Первичное выражение

Выражение строится на основе операций, объединяющих операнды. Основным элементом выражения является первичное выражение. Первичное выражение — это фактически элементарный строительный блок любого выражения. Следующее множество БНФ определяет синтаксис первичного выражения:

ПервичноеВыражение ::= Литерал
::= Имя
::= (Выражение)
::= this
::= ::ИмяОператорнойФункции
::= ::КвалифицированноеИмя
::= ::Идентификатор

Понятие литерала ранее уже обсуждалось.

Нетерминальный символ Имя также определяется с помощью соответствующего множества БНФ:
Имя ::= Идентификатор
::= ИмяОператорнойФункции
::= ИмяФункцииПриведения
::= КвалифицированноеИмя
::= ~ИмяКласса

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

В C++ не существует выражений без типа и значения. Даже в том случае, когда говорят, что значение выражения не определено, выражение всё же имеет значение соответствующего типа. Это случайное значение.

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

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

Сложность первичного выражения ничем не ограничивается. Заключённое в круглые скобки выражение рассматривается как первичное выражение.

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

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

Ничего нельзя сказать о том, что находится вне области видимости. Для транслятора C++ это потусторонний мир. И поэтому не случайно в соответствующей форме Бэкуса-Наура после операции разрешения области видимости используется терминальный символ Идентификатор, а не Имя. Идентификатор становится именем лишь после соответствующего объявления. В момент выполнения операции разрешения области видимости нельзя утверждать, что её операнд является именем.

Уже из определения первичного выражения видно, что в C++ сложность выражения ничем не ограничивается. Вместе с тем любое правильно построенное выражение может быть успешно распознано и систематизировано. Здесь всё зависит от контекста, а фактически от символа «соединяющей» операнды операции.

Константные выражения

КонстантноеВыражение ::= УсловноеВыражение

В ряде случаев C++ требует, чтобы вычисляемое значение выражения было целочисленной константой. Это относится к границам массивов, размерам битовых полей, значениям инициализаторов элементов перечисления. Константные выражения представляют собой неизменяемые целочисленные значения. Они строятся на основе литералов, элементов перечисления (о них речь впереди), проинициализированных целочисленных констант, выражений, построенных на основе операции sizeof.

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

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

Константное выражение может состоять из литералов, имён констант, элементов перечисления (о них позже), может содержать символы арифметических операций, которые связывают константные выражения.

Основное назначение константного выражения в C++ — фиксация значений ограниченного множества значений, предназначенных для организации управленния процессом выполнения программы, задание предопределённых характеристик объектов (например, размер массива). Управление выполнением и характеристика размерности не требует особой точности. Органы управленния должны быть максимально простыми, количество элементов и длина в байтах задаются целочисленными значениями. Здесь нет проблем, связанных с точностью вычисления, здесь достаточно значений интегрального типа.

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

По этой же причине константное выражение не может быть указателем или ссылкой (о ссылках — позже), поскольку всё, что связано с адресами, определяется лишь на этапе выполнения программы.

Константное выражение не может содержать операцию присваивания, операции инкрементации и декрементации.
А вот операции сравнения, арифметические операции, операция sizeof и, как ни странно, операция запятая не вызывают возражений транслятора (транслятор и считать умеет, и сравнивать, он и размеры определяет, а также понимает, какое значение следует присвоить выражению, содержащему символ операции запятая).

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты