|
Программирование >> Программирование на языке c++
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; -♦ разрешается доопределять глобальные операторы (они будут доступны в теле любой функции) и локальные
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |