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

 

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

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

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

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

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

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

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

то есть Синтаксис этих операций следующий:

void *operator new(size_t size);

void operator delete (void *);

где void * - указатель на область памяти, выделяемую под объект, size - размер объекта в байтах, size_t - тип размерности области памяти, int или long.

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

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

 

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

operator имя_нового_типа ():

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

Пример:

Number::operator int(){return n;}

Number Peremennaya;

cout << int(Peremennaya);

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

 

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

class max{

public:

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

{

return a > b:

}

};

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

max x:

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

cout << max()(5. 1) << endl: // Результат - 1

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

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

Операцию ( ) (а также операцию [ ]) можно определять только как метод класса. Можно определить перегруженные операции вызова функции с различным количеством аргументов. Функциональные объекты широко применяются в стандартной библиотеке C++.

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

 

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