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

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

if (&M == this) return *this; if (name) delete [] name; if (M.name){

name = new char [strlen(M.name) + 1]; strcpy(name, M.name);} else name = 0;

health = M.health; ammo = M.ammo; skin = M.skin; return *this; } Возврат из функции указателя на объект делает возможной цепочку операций присваивания:

monstr A(10). В, С; С = В = А;

Операцию присваивания можно определять только как метод класса. Она не наследуется.

Перегрузка операций new и delete

Чтобы обеспечить альтернативные варианты управления памятью, можно определять собственные варианты операций new и new[] для выделения динамической памяти под объект и массив объектов соответственно, а также операции delete и delete [] для ее освобождения.

Эти функции-операции должны соответствовать следующим правилам:

  • им не требуется передавать параметр типа класса;

  • первым параметром функциям new и new[] должен передаваться размер объекта типа size_t (это тип, возвращаемый операцией sizeof, он определяется в заголовочном файле <stddef.h>); при вызове он передается в функции неявным образом;

  • они должны определяться с типом возвращаемого значения void*, даже если return возвращает указатель на другие типы (чаще всего на класс);

  • операция delete должна иметь тип возврата void и первый аргумент типа

void*;

□ операции выделения и освобождения памяти являются статическими элемен тами класса.

Поведение перегруженных операций должно соответствовать действиям, выполняемым ими по умолчанию. Для операции new это означает, что она должна возвращать правильное значение, корректно обрабатывать запрос на выделение памяти нулевого размера и порождать исключение при невозможности выполнения запроса (об исключениях рассказывается в разделе «Обработка исключительных ситуаций» на с. 222). Для операции delete следует соблюдать условие, что удаление нулевого указателя должно быть безопасным, поэтому внутри операции необходима проверка указателя на нуль и отсутствие каких-либо действий в случае равенства.

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

193

Стандартные операции выделения и освобождения памяти могут использоваться в области действия класса наряду с перегруженными (с помощью операции доступа к области видимости :: для объектов этого класса и непосредственно — для любых других).

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

class Obj {...}; class pObj{

private: Obj *p; }: При выделении памяти под объект типа pObj с помощью стандартной операции

new

pObj *p - new pObj:

фактическое количество байтов будет превышать sizeof(pObj), поскольку new обычно записывает в начало выделяемой области ее размер (для того чтобы правильно отрабатывала операция delete):

Для небольших объектов эти накладные расходы могут оказаться весьма значительными. Для экономии памяти можно написать собственную операцию new класса pObj, которая будет выделять большой блок памяти, а затем размещать в нем указатели на Obj. Для этого в объект pObj вводится статическое поле headOf Free, в котором хранится указатель на первую свободную ячейку блока для размещения очередного объекта.

Неиспользуемые ячейки связываются в список. Чтобы не занимать память под поле связи, используется объединение (union), с помощью которого одна и та же ячейка используется либо для размещения указателя на объект, либо для связи со следующей свободной ячейкой:

class pObj{ public:

static void * operator new(size_t size):

private: union{

Obj *p; // Указатель на объект

pObj *next; // Указатель на следующую свободную ячейку

}:

static const int BLOCK_SIZE;// Размер блока // Заголовок списка свободных ячеек: static pObj *headOfFree;

}:

void * pObj::operator new(size_t size){

// Перенаправить запросы неверного количества памяти

194