Лекции.Орг


Поиск:




Создание объектов с различным временем жизни




Статические объекты создаются при запуске программы в сегменте данных и существуют до закрытия. Конструкторы для таких объектов вызываются неявно в порядке поступления объектов на вход компоновщика. Деструкторы вызываются при окончании работы программы в порядке обратном порядку вызова конструктора.

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

Динамические объекты создаются, инициализируются и уничтожатся по требованию программиста при помощи операторов new и delete. Операция new кроме выделения памяти определяет вызов соответствующего конструктора. Delete – соответствующий деструктор. Для объектов пользовательского типа надо пользоваться только new и delete, а не fmalloc, потому что malloc не вызывает конструктора. То же самое происходит и при delete.

Допускается создание и инициализация статических и динамических массивов из объекта класса. Синтаксис напоминает создание обыкновенных

Point2D P1[3]={Point2D(2,4),Point2D(1,4),Point2D(4,6)};

Point2D P[3]={5,3,1};

Point2D P1[3]={Point2D(4),Point2D(1),Point2D(6)};

Point2D P1[3]={Point2D(4),Point2D(1,4),6}; //для первого вызывается с одним параметром, потом с двумя параметров, а потом конструктор по умолчанию

На первый взгляд, кажется, что для каждого элемента массива создается временный объект, а потом массив инициализируется этими временными объектами. На самом деле никаких лишних действий компилятор не производит.


 

Массивы объектов класса

Допускается создание и инициализация статических и автоматических массивов из объектов класса. Синтаксически инициализация напоминает синтаксис для стандартных типов данных.

Point2D P1[3]={Point2D(2,4),Point2D(3,3),Point2D(4,6)};

Point2D P2[3]={Point2D(5),Point2D(4),Point2D(3)};

Point2D P3[3]={5,4,3};

Point2D P4[3]={Point2D(4),5,Point2D(3,1)};

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

Если у класса конструктор операции new [], можно создать массив в динамической области памяти. Инициализация такого массива не допустима.

Point2D *pArray= new Point2D[20];

...........

delete [] pArray;

Операция new гарантирует вызов конструктора для каждого объекта массива. Чтобы можно было описать массив объектов класса с конструктором, этот класс должен иметь стандартный конструктор, т.е. конструктор, вызываемый без параметров. Например, в соответствии с определением

table tbl[10];

будет создан массив из 10 таблиц, каждая из которых инициализируется вызовом table::table(15), поскольку вызов table::table() будет происходить с фактическим параметром 15.

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

Когда уничтожается массив, деструктор должен вызываться для каждого элемента массива. Для массивов, которые размещаются не с помощью new, это делается неявно. Однако для размещенных в свободной памяти массивов неявно вызывать деструктор нельзя, поскольку транслятор не отличит указатель на отдельный объект массива от указателя на начало массива, например:

void f()

{ table* t1 = new table; table* t2 = new table[10]; delete t1; // удаляется одна таблица delete t2; // неприятность: // на самом деле удаляется 10 таблиц}

В данном случае программист должен указать, что t2 - указатель на массив:

void g(int sz){ table* t1 = new table; table* t2 = new table[sz]; delete t1; delete[] t2;} Функция размещения хранит число элементов для каждого размещаемого массива. Требование использовать для удаления массивов только операцию delete[] освобождает функцию размещения от обязанности хранить счетчики числа элементов для каждого массива. Исполнение такой обязанности в реализациях С++ вызывало бы существенные потери времени и памяти и нарушило совместимость с С.




Поделиться с друзьями:


Дата добавления: 2016-07-29; Мы поможем в написании ваших работ!; просмотров: 553 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Победа - это еще не все, все - это постоянное желание побеждать. © Винс Ломбарди
==> читать все изречения...

787 - | 763 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.014 с.