logo
volkov / C++ / Бьерн Страуструп-Справочное руководство по С++

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'

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

операции умножения.