Категории
Самые читаемые
RUSBOOK.SU » Компьютеры и Интернет » Программирование » Справочное руководство по C++ - Бьярн Страустрап

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

Читать онлайн Справочное руководство по C++ - Бьярн Страустрап

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 3 4 5 6 7 8 9 10 11 ... 41
Перейти на страницу:

Операция 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 [].

R.5.4 Явное преобразование типа

Явное преобразование типа можно задать с помощью функциональной записи (§R.5.2.3) или с помощью операции приведения.

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

 унарное-выражение

 (имя-типа) выражение-приведения

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

В операции приведения нельзя определять типы.

Всякое преобразование типа, не упомянутое здесь и не являющееся преобразованием явно определенным пользователем (§R.12.3), считается ошибкой.

Любой тип, который можно преобразовать в другой с помощью стандартного преобразования (§R.4), можно также преобразовать с помощью явного преобразования (приведения) и смысл преобразования будет тот же.

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

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

1 ... 3 4 5 6 7 8 9 10 11 ... 41
Перейти на страницу:
На этой странице вы можете бесплатно скачать Справочное руководство по C++ - Бьярн Страустрап торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Сергій
Сергій 25.01.2024 - 17:17
"Убийство миссис Спэнлоу" от Агаты Кристи – это великолепный детектив, который завораживает с первой страницы и держит в напряжении до последнего момента. Кристи, как всегда, мастерски строит