|
Операция 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])(); // ошибка
может привести к ошибке, т.к. операции применяются в таком порядке
(new int) (*[10])(); // ошибка
Объекты сложного типа можно задать в операции new с помощью явно указанных скобок, например, обращение
new (int (*[10])());
размещает массив из 10 указателей на функции (не имеющие параметров
и возвращающие int).
Конструкции имя-типа-new в выражение-размещения должна быть
самой длинной из возможных последовательностей конструкций
описатель-new. Это предотвращает коллизии между операциями из
описателей &, *, [] и их двойниками из выражения, например,
new int* i; // синтаксическая ошибка: разобрано как `(new int*) i' // не как `(new int)*i'
Символ * используется в описателе указателя, а не в качестве операции умножения.