Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
62
Добавлен:
02.05.2014
Размер:
543.23 Кб
Скачать

2. Функции operator new() и operator delete()

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

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

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

Динамическая память не опустошается автоматически. "Гибель" локального указателя, настроенного на выделенную область динамической памяти означает всего лишь потерю доступа к этой области памяти. В этом случае уничтожается указатель, но освобождения памяти не происходит.

Для освобождения памяти используется операция (операторная функция) delete. Подобно операторной функции new, delete также является статическим членом класса.

В контексте выражений размещения и удаления могут быть использованы стандартные операции C++ new и delete, а может быть обеспечен вызов операторных функций operator new и operator delete.

#include <iostream.h>

#include "TypeX.h"

void main()

{

TypeX *xPoint = NULL, *xPointP = NULL, *xxPointP = NULL;

xPoint = new TypeX;

xPointP = new TypeX(25);

// Выражение размещения может содержать параметры.

// Так осуществляется управление конструктором.

xxPointP = new (125+25) TypeX(50);

// Выражение размещения может включать размещение.

// Этот одноэлементный список выражений обеспечивает передачу

// значений параметров операторной функции operator new.

// Альтернативные формы вызова операторных функций:

// ИмяТипа в круглых скобках.

// xPoint = new (TypeX);

// xPointP = new (TypeX)(25);

// xxPointP = new (125+25) (TypeX)(50);

delete xPoint;

delete xPointP;

delete xxPointP;

cout << "OK" << endl;

}

Билет 15

1. Объединения

Мы возвращаемся к объединениям. Наш уровень знаний делает знакомство с этой конструкцией приятным и лёгким.

Объединение можно представить в виде структуры, размер которой достаточен для сохранения не более одного данного-члена объединения. Это конструкция для экономии памяти. Здесь может быть ничего лишнего. Отсюда его основные свойства и особенности:

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

  • объединение не может иметь базовых классов и само также не может служить базовым классом. По этой причине в объединения не могут входить виртуальные функции (они бесполезны);

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

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

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

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

#include <iostream.h>

union

{

float floatVal;

struct

{

int bit0 : 1;

int bit1 : 1;

int bit2 : 1;

int bit3 : 1;

int bit4 : 1;

int bit5 : 1;

int bit6 : 1;

int bit7 : 1;

int bit8 : 1;

int bit9 : 1;

int bit10 : 1;

int bit11 : 1;

int bit12 : 1;

int bit13 : 1;

int bit14 : 1;

int bit15 : 1;

int bit16 : 1;

int bit17 : 1;

int bit18 : 1;

int bit19 : 1;

int bit20 : 1;

int bit21 : 1;

int bit22 : 1;

int bit23 : 1;

int bit24 : 1;

int bit25 : 1;

int bit26 : 1;

int bit27 : 1;

int bit28 : 1;

int bit29 : 1;

int bit30 : 1;

int bit31 : 1;

} BitField;

} MyUnion;

void main ()

{

MyUnion.BitField.bit31 = 0;

MyUnion.BitField.bit30 = 1;

MyUnion.BitField.bit29 = 0;

MyUnion.BitField.bit28 = 0;

MyUnion.BitField.bit27 = 0;

MyUnion.BitField.bit26 = 0;

MyUnion.BitField.bit25 = 1;

MyUnion.BitField.bit24 = 1;

MyUnion.BitField.bit23 = 0;

MyUnion.BitField.bit22 = 0;

MyUnion.BitField.bit21 = 1;

MyUnion.BitField.bit20 = 1;

MyUnion.BitField.bit19 = 0;

MyUnion.BitField.bit18 = 0;

MyUnion.BitField.bit17 = 1;

MyUnion.BitField.bit16 = 0;

MyUnion.BitField.bit15 = 0;

MyUnion.BitField.bit14 = 0;

MyUnion.BitField.bit13 = 1;

MyUnion.BitField.bit12 = 0;

MyUnion.BitField.bit11 = 0;

MyUnion.BitField.bit10 = 0;

MyUnion.BitField.bit9 = 0;

MyUnion.BitField.bit8 = 0;

MyUnion.BitField.bit7 = 0;

MyUnion.BitField.bit6 = 0;

MyUnion.BitField.bit5 = 0;

MyUnion.BitField.bit4 = 0;

MyUnion.BitField.bit3 = 0;

MyUnion.BitField.bit2 = 0;

MyUnion.BitField.bit1 = 0;

MyUnion.BitField.bit0 = 0;

cout << MyUnion.floatVal << endl;

}

Соседние файлы в папке Програмки на C++