Скачиваний:
50
Добавлен:
15.06.2014
Размер:
471.04 Кб
Скачать

21

Определение манипуляторов с параметрами 2

Продолжение примера:

char *money::CurM; // Static pointer

void func( ios_base& os, char * somename )

{

money::setpic(somename);

}

_Smanip<charp> setpic(char * somename)

{

return (_Smanip<charp>(&func, somename));

}

void main ()

{

money amt = (long)54321;

cout << setpic( "$") << "amount = " << amt << endl; // Альтернатива Br или €

}

22

Перегрузка оператора new

ВС++ имеются две возможности перегрузки операторов new() и delete()

-локально (в пределах класса) и глобально (в пределах программы). Эти операторы имеют правила переопределения, отличные от рассмотренных правил переопределения других операторов.

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

Оператор new можно задать в следующих формах:

<::> new <аргументы> имя_типа <инициализирующее_выражение>;

<::> new <аргументы> имя_типа [ ];

Параметр ”аргументы” можно использовать либо для того, чтобы различить разные версии глобальных операторов new, либо для использования их в теле функции operator. Доопределенную функцию operator new можно объявить:

void *operator new(size_t t, <список _аргументов>); void *operator new[](size_t t, <список _аргументов>);

Вторая форма используется для выделения памяти для массивов. Возвращаемое значение всегда должно иметь тип void *. Единственный

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

23

Перегрузка оператора new - пример

#include "iostream“ using namespace std;

void *operator new(size_t tip, int kol)

//глобальная ф-ция operator

new

// с одним параметром

{ cout << "GF 1" <<endl;

return new char[tip*kol];

 

}

void *operator new(size_t tip,int n1,int n2) //глобальная ф-ция operator new

{ cout << "GF 2" <<endl; // с двумя параметрами void *p=new char[tip*n1*n2];

return p;

}

class cls

{ char a[40]; public:

cls(char *aa){ strcpy(a,aa); } ~cls(){}

void *operator new(size_t,int);

};

24

Перегрузка оператора new - пример

void *cls::operator new(size_t tp,int n) // локальная функция operator new

{ cout << "LF " <<endl; return new char[tp*n];

}

void main()

{cls obj("Overload of the operator new"); float *ptr1;

ptr1=new (5) float;

// вызов 1 глобальной функции

operator

new

 

 

ptr1=new (2,3) float;

// вызов 2 глобальной функции

operator

new

 

 

ptr1=new float;

// вызов сиcтемной глобальной функции

cls *ptr2=new (3) cls("aa"); // вызов локальной функции operator

warning C4291: 'void *cls::operator new(size_t,int)' : no matching operator delete found; memory will not be freed if initialization throws an exception

25

Перегрузка оператора delete

Оператор delete разрешается доопределять только по

отношению к классу. В то же время можно заменить

системную версию реализации оператора delete на свою.

Доопределенную функцию operator delete можно

объявить:

void operator delete(void *p<,size_t t>); void operator delete[](void *p<,size_t t>);

Функция operator должна возвращать значение void и

имеет один обязательный аргумент типа void * - указатель на область памяти, которая должна быть освобождена.

26

Перегрузка оператора delete - пример

class cls {

void operator delete(void *);

}

void cls::operator delete(void *p)

// локальная функция operator

{ cout << “LF DELETE" <<endl;

 

delete p;

// вызов системной функции delete

}

 

 

void operator delete[](void *p)

// глобальная функция operator

{ cout << “GF DELETE" <<endl;

 

delete p;

// вызов системной функции delete

}

 

 

27

Перегрузка оператора delete - использование

void main()

 

 

{ cls obj("перегрузка операторов NEW и DELETE");

 

float *ptr1;

// вызов глобальной ф-ции

доопр. оператора

ptr1=new (5) float;

new

// вызов глобальной ф-ции

доопр.оператора

delete [] ptr1;

delete

 

 

cls *ptr2=new (10) cls("aa"); // вызов локальной функции доопределения

// оператора new (из класса cls) delete ptr2; // вызов локальной функции

доопределения

// оператора delete (из класса cls)

}использоваться оператор delete[], так как это приведет к бесконечной рекурсии. При выполнении инструкции системный оператор delete ptr2 сначала вызывается локальная функция доопределения оператора delete для класса cls, а затем из нее глобальная функция переопределения delete.

28

Перегрузка операторов new – delete

warning C4291: 'void *cls::operator new(size_t,int)' : no matching operator delete found; memory will not be freed if initialization throws an exception

Нужны добавки!

class cls { …

void operator delete(void *,int);

};

void cls::operator delete(void *p, int n) // локальная функция

operator

 

{

 

cout << "LFD" <<endl;

 

delete p;

// вызов системной функции

delete

 

}