Сделай Сам Свою Работу на 5

R.5.3.1 Инкремент и декремент





 

Операнд префиксной операции ++ увеличивается на 1. Операнд должен быть изменяемым адресом. Тип операнда должен быть арифметическим или указателем. Результатом является новое значение операнда, оно считается адресом. Выражение ++x эквивалентно x+=1. Для уточнения преобразований можно обратиться к описанию сложения (§R.5.7) и операций присваивания (§R.5.17).

Префиксная операция -- сводится к уменьшению на 1 и выполняется аналогично префиксной операции ++.

 

R.5.3.2 Операция sizeof

 

Операция sizeof вычисляет размер своего операнда в байтах. Операнд должен быть или выражением, которое не вычисляется, или именем типа в скобках. Операцию sizeof нельзя применять к функции, битовому полю, неопределенному классу, типу void или к массиву с неуказанными границами индексов. Байт никак не определяется языком, кроме как результата операции sizeof, именно sizeof(char) есть 1.

Если операция применяется к ссылке, результатом будет размер объекта, на который настроена ссылка. Если она применяется к классу, результатом будет размер объекта этого класса в байтах с учетом всех дополнительных байтов, которые потребуется для размещения такого объекта в массиве. Размер любого класса или объекта класса больше нуля. В случае массива операция выдает полное число байтов в массиве. Отсюда следует, что размер массива из n элементов равен размеру элемента, умноженному на n.



Операция sizeof может применяться к указателю на функцию, но не к самой функции.

Результатом операции будет константа типа size_t. Этот тип определен в стандартном заголовочном файле ‹stddef.h› и является зависящим от реализации беззнаковым целочисленным типом.

 

R.5.3.3 Операция new

 

Операция new предназначена для создания объекта типа имя-типа (§R.8.1). Этот тип должен быть типом объекта и функции нельзя размещать с ее помощью, хотя указатели на функции можно.

выражение-размещения:

::opt new параметры-new opt имя-типа-new инициализатор-new

::opt new параметры-new opt (имя-типа) инициализатор-new

параметры-new:

( список-выражений )

имя-типа-new:

список-спецификаций-типа описатель-new opt

описатель-new:

* список-спецификаций-cv opt описатель-new opt

имя-класса :: список-спецификаций-cv opt описатель-new opt



описатель-new opt [ выражение ]

инициализатор-new:

( список-инициализаторов opt )

Время жизни объекта, созданного с помощью new, не ограничивается областью видимости, в которой он был создан. Операция new возвращает указатель на созданный объект. Если объект является массивом, возвращается указатель на начальный элемент массива. Например, обе операции new int и new int[1] возвратят int*, а типом new int[i][10] будет int(*)[10]. Если описывается тип массива (§R.8.2.4), все размерности, кроме первой, должны быть выражениями-константами (§R.5.19) с положительным значением. Первая размерность массива может задаваться произвольным выражением, даже если используется имя-типа (здесь нарушается общее требование, чтобы размерности массива в конструкции имя-типа были выражениями-константами (§R.5.19)).

Допускается, чтобы вызывалась функция operator new() с параметром нуль. В таком случае возвращается указатель на объект. При повторении таких вызовов будут возвращаться указатели на разные объекты.

Конструкция список-спецификаций-типа не должна содержать const, volatile, описание класса или перечисления.

Для резервирования памяти операция new обращается к функции operator new() (§R.12.5). При размещении объекта типа T ей в качестве первого параметра передается sizeof(T). Конструкция параметры-new используется для передачи дополнительных параметров. Например, операция new T приводит к вызову operator new(sizeof(T)), а операция new(2,f) T приводит к вызову operator new(sizeof(T),2,f).

Конструкция параметры-new может использоваться только, если описана функция operator new() с параметрами соответствующих типов.

Если с помощью операции new создается объект не типа класс (в том числе и массив объектов типа класс), то вызывается глобальная функция ::operator new(). Если с помощью new создается объект класса T, вызывается функция T::operator new(), если она существует (используя обычные правила просмотра при поиске членов класса и его базовых классов, §R.10.1.1), иначе вызывается глобальная функция ::operator new(). Использование операции ::new() гарантирует, что будет вызываться глобальная функция ::operator new(), даже если существует T::operator new().



Конструкция выражение-размещения может содержать инициализатор-new. Для объектов классов с конструкторами (§R.12.1) задаваемый ею список параметров будет использоваться при вызове конструктора, в других случаях конструкция инициализатор-new должна иметь вид (выражение) или (). Если выражение присутствует, оно используется для инициализации объекта, если его нет, объект начнет существование с неопределенным значением.

Если класс имеет конструктор, объект этого класса можно создать с помощью new только при условии, что заданы подходящие параметры, или, что класс имеет стандартный конструктор (§R.12.1). Отводит ли память при создании объекта типа класс сама функция operator new, или оставляет это на конструктор, зависит от реализации. Как для конструктора, так и для функции operator new() проводится проверка возможности доступа и однозначности (§R.12).

Для массивов нельзя задавать инициализаторы. Массивы объектов типа класса с конструктором можно создавать с помощью операции new только, если конструктор класса является стандартным (§R.12.1). В этом случае стандартный конструктор будет вызываться для каждого элемента массива.

Инициализация производится только в том случае, когда функция operator new() возвращает ненуль. Если она возвращает 0 (пустой указатель), значение выражения есть 0.

Порядок вычисления выражения вызова operator new() для получения памяти и порядок вычисления параметров конструктора неопределен. Так же неопределено вычисляются ли параметры конструктора, если функция operator new() возвратила 0.

В конструкции имя-типа-new скобки использовать необязательно. Тогда обращение

new int (*[10])(); // error

может привести к ошибке, т.к. операции применяются в таком порядке

(new int) (*[10])(); // error

Объекты сложного типа можно задать в операции new с помощью явно указанных скобок, например, обращение

new (int (*[10])());

размещает массив из 10 указателей на функции (не имеющие параметров и возвращающие int).

Конструкции имя-типа-new в выражение-размещения должна быть самой длинной из возможных последовательностей конструкций описатель-new. Это предотвращает коллизии между операциями из описателей &, *, [] и их двойниками из выражения, например,

new int* i; // syntax error: parsed as `(new int*) i'

// not s `(new int)*i'

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

 

R.5.3.4 Операция delete

 

Операция delete уничтожает объект, созданный с помощью new.

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

::opt delete выражение-приведения

::opt delete [] выражение-приведения

Результат имеет тип void. Операндом delete должен быть указатель, который возвращает new. Эффект применения операции delete к указателю, который не получен в результате операции new без задания параметры-new, считается неопределенным и обычно приводит к опасным последствиям. Однако гарантируется, что удаление по указателю с нулевым значением безопасно.

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

Нельзя удалять указатель на константу.

Операция delete вызывает деструктор (если он есть $$12.4) для объекта, на который настроен ее операнд.

Для освобождения памяти, отведенной под указываемый объект, операция delete вызывает функцию operator delete (§R.12.5). Для объектов, не имеющих тип класс (в том числе и для массивов классов), используется глобальная функция ::operator delete(). Для объекта типа класс T вызывается функция T::operator delete(), если она есть (используя обычные правила просмотра при поиске членов класса и производных от него классов, §R.10.1.1), в противном случае вызывается глобальная функция::operator delete(). Обращение ::delete гарантирует, что будет вызываться глобальная функция ::operator delete(), даже если существует T::operator delete(). Для удаления массивов используется обращение вида

delete [] выражение-приведения

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

Результат удаления массива с помощью простого обращения delete неопределен, так же как и удаление одиночного объекта с помощью delete [].

 

 

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.