Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Часть II. Объектно-ориентированное программирование

// стандартной операции new:

if (size !«. sizeof(pObj)) return -operator new(size);

pObj *p = headOfFree; // Указатель на первую свободную ячейку

// Переместить указатель списка свободных ячеек:

if (p) headOfFree - р -> next:

// Если свободной памяти нет. выделяем очередной блок:

else {

pObj *newblock = stati c__cast<pObj*^

(-operator new(BLOCK_SIZE * sizeof(pObj))):

// Все ячейки свободны, кроме первой (она будет

// занята), связываем их:

for (int i - 1: i< BLOCK_SIZE - 1: ++i) newblock[i].next = &newblock[i + 1];

newblock[BLOCK__SIZE - l].next = 0:

// Устанавливаем начало списка свободных ячеек:

headOfFree = &newblock[l];

р = newblock;

} return p; // Возвращаем указатель на выделенную память

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

В программе, использующей класс pObj, должна присутствовать инициализация его статических полей (статические поля рассматривались на с. 186):

pObj *pObj: -.headOfFree: // Устанавливается в 0 по умолчанию const int pObj::BLOCK_SIZE - 1024:

Как видно из этого примера, помимо экономии памяти достигается еще и высокое быстродействие, ведь в большинстве случаев выделение памяти сводится к нескольким простым операторам.

Естественно, что если операция new перегружена, то же самое должно быть выполнено и для операции delete (например, в нашем случае стандартная операция del ete не найдет в начале объекта верной информации о его размерах, что приведет к неопределенному поведению программы).

В рассмотренном примере операция delete должна добавлять освобожденную ячейку памяти к списку свободных ячеек:

void pObj::operator deleteCvoid * ObjToDie, size_t size){ if (ObjToDie «— 0) return: if (size !- sizeof(pObj)){

Здесь использовано явное преобразование типа с помощью операции static_cast. О нем рассказывается в разделе «Операция static_cast* на с. 237.

Глава 4. Классы

195

-operator delete(ObjToDie); return;

}

pObj *p = static_cast<pObjMObjToDie);

p->next = headOfFree;

headOfFree = p; } В операции delete выполнена проверка соответствия размеров объектов, аналогичная приведенной в операции new.

Перегрузка операции приведения типа

Можно определить функции-операции, которые будут осуществлять преобразование объекта класса к другому типу. Формат:

operator имя_нового_типа О;

Тип возвращаемого значения и параметры указывать не требуется. Можно определять виртуальные функции преобразования типа.

Пример:

.monstr::operator int(){return health;}

monstr Vasia; cout « int(Vasia):

Перегрузка операции вызова функции

Класс, в котором определена операция вызова функции, называется функциональным, От такого класса не требуется наличия других полей и методов:

class if_greater{ public:

int operator О (int a. int b) const {

return a > b: } }: Использование такого класса имеет весьма специфический синтаксис. Рассмотрим пример:

if_greater x;

cout « х(1. 5) « endl; // Результат - О

cout « if_greater()(5. 1) « endl; // Результат - 1

Поскольку в классе if_greater определена операция вызова функции с двумя параметрами, выражение х(1, 5) является допустимым (то же самое можно записать в виде х. operator О (1. 5)). Как видно из примера, объект функционального класса используется так, как если бы он был функцией.

Во втором операторе вывода выражение if_greater() используется для вызова конструктора по умолчанию класса if_greater. Результатом выполнения этого выражения является объект класса if_greater. Далее, как и в предыдущем случае, для этого объекта вызывается функция с двумя аргументами, записанными в круглых скобках.

196