Программирование >>  Программирование на языке c++ 

1 ... 69 70 71 [ 72 ] 73 74 75 ... 159


delete I;

Следующий пример демонстрирует доопределение глобальной функции new для массивов.

#include <iostreain.h> #include <alloc.h>

void* operator new[](size t t,int n) доопределение new

для массивов

{ cout 1: t*n endl;

return new char[t*n]; } void main(void)

{ double *d=new(5) doub!e[3]; Результат: 1: 120

int *i=new int[10]; использование заданного в языке по умолчанию глобального оператора

здесь можно выполнять какие-то действия delete []d; delete [ji;

Глобальные операторы delete (для массивов и для не массивов) не могут быть доопределены (т. е. нельзя использовать несколько версий таких операторов). Однако заданные в самом языке глобальные операторы можно изменить (т. е. заменить версию, заданную в языке по умолчанию, на свою версию).

Операторы new и delete разрешается переопределить по отношению к классу. В этом случае переопределенную функцию operator delete можно объявить в таких формах: void operator delete(void *pointer, [size t t]);

для не массивов void operator delete[ ](void *pointer, [size t t]);

для массивов

Она должна всегда возвращать значение типа void и иметь первый (и единственный обязательный) аргумент типа void*, указывающий на объект или массив, которые надо удалить из памяти (для которых надо освободить память).

Пусть задан класс А и для него определены новые функции new и delete: A::operator new(), A::operator newQO,



A::operator delete() и A::operator deleteQO. В этом сшучае все эти функции будут статическими компонентами класса А независимо от того, использовался или нет спецификатор static. Это означает, что они не могут быть виртуальными функциями. Глобальные операторы new и delete, заданные в языке по умолчанию, можно использовать в классе А: либо в теле новых функций operator new и operator delete при их определении, либо в теле других функций класса А. В последнем случае надо задать полные имена соответствующих глобальных функций, например ::new.

Рассмотрим пример переопределения функций new и delete в некотором классе BASE (см. § 4.7, где поясняется необходимость введения в базовый класс BASE виртуального деструктора).

#include <iostream.h>

class BASE { базовый класс

public:

BASEO { cout cb\t ;} конструктор

virtual ~BASE() { cout db\t ;} виртуальный

деструктор void* operator new(size t s) { здесь можно выполнить какое-то специфическое вьщеление памяти для этого класса

return new char[s]; } void operator delete(void* p) { здесь можно выполнить какое-то специфическое освобождение памяти для этого класса delete []р; }

class DERIVED : public BASE { производный класс public:

DERIVEDO { cout cd\t ;} конструктор -DERIVEDQ { cout dd\t ;} деструктор

void main(void) {

BASE *p = new DERIVED; Результат: cb cd какие-то действия с объектом *р



delete р; Результат: dd db

Программа позволяет правильно выделять и освобождать память под базовый и производный объекты, даже если соответствующие действия выполняются через указатель на базовый класс (что и сделано в приведенном примере). Здесь сЬ - конструктор базового класса, cd - конструктор производного класса, dd - деструктор производного класса, db - деструктор базового класса.

Из приведенного примера видно, что переопределенные операторы new и delete наследуются в производных классах (как и другие операторы, кроме оператора присваивания =).

5.10. Заключение

Сформулируем основные выводы и правила доопределения операторов: >- механизм доопределения операторов отражает концепцию полиморфизма и является существенным средством поддержки абстрактных типов данных; все операторы, перечисленные в § 5.2, можно доопределить. Фактически - это все операторы языка С++ за исключением . .* :: ?: sizeof и символов препроцессора # и ##;

компилятор различает разные операторы путем проверки числа и(или) типов их операндов (аргументов);

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

различают бинарные (двухоперандные) и унарные (однооперандные) операторы. Каждый оператор, заданный в самом языке, имеет определенное число операндов, свой приоритет и выполняется в выражении слева направо либо справа налево. Все эти правила, установленные для оператора в языке, сохраняются и для доопределенных операторов, т. е. эти правила нельзя изменить функцией operator;

-♦ разрешается доопределять глобальные операторы (они будут доступны в теле любой функции) и локальные



1 ... 69 70 71 [ 72 ] 73 74 75 ... 159

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика