Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lections_rus.doc
Скачиваний:
31
Добавлен:
06.02.2016
Размер:
1.41 Mб
Скачать

5.4. Перегрузка операторов new, new[], delete, delete[]

Имеется возможность перегрузить new и delete. Это можно сделать в том случае, если необходимо использовать какой-то особый способ выделения памяти. Например, нужно выделять память и, в случае отсутствия её, создавать дисковый файл, в который можно записывать информацию. Какой бы ни была причина, осуществить такую перегрузку очень просто.

Для перегрузки операторов new и delete может использоваться следующий формат:

Void* operator new(size_t размер){ код оператора

     return указатель_на_память; }

Void operator delete(void* p){ код оператора }

Параметр размер будет содержать число в байтах, которое необходимо выделить для размещения объекта.Это значение будет сформировано автоматически. У параметра размер тип данных size_t. Данный тип - это псевдоним, под которым скрывается unsigned int. В прототипе оператора new можно указать дополнительные параметры, которые будут передаваться при вызове new. Самое главное, чтобы на первом месте в обьявлении функции находился параметр типа size_t. Перегруженная функция new должна возвращать указатель на выделенную память. По отношению к классу перегруженный оператор new будет статической функцией-членом.

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

Для перегрузки операторов new [] и delete [] может использоваться следующий формат:

Void* operator new[](size_t размер){ код оператора return указатель_на_память; }

Void operator delete[](void* p){ код оператора }

Всё вышесказанное о new и delete верно и по отношению к new [] , delete [].

Любая теория всегда должна закрепляться практикой !!! Поэтому давайте рассмотрим пример перегрузки new и delete. В нашем примере будет производиться подсчет динамически созданных объектов класса под названием SomeClass.

Исходный код примера можно найти в папке New

#include<iostream.h>

#include <malloc.h>

// Класс для обьектов, которого будет производиться подсчет

class SomeClass{

// статическая переменная, счетчик

static int counter;

public:

// Функция, возвращающая текущее значение счетчика

static int GetCounter();

public:

// перегруженные операторы new и delete,

// обратите внимание на дополнительные

// параметры передаваемые внутрь операторов

void * operator new(size_t size,int val, char* str = "New Operator");

void operator delete(void* ptr);

// перегруженные операторы new [] и delete []

void * operator new [] (size_t fullsize, char* str = "New [] ");

void operator delete [] (void* ptr);

};

int SomeClass::counter = 0;

int SomeClass::GetCounter()

{

return counter;

}

void * SomeClass::operator new( size_t size,int val,char* str)

{

cout<<"\n**************\n";

for(int i = 0; i < val; i++)

{

cout << "\n" << str << "\n";

}

cout<<"\n**************\n";

/*

Для выделения памяти используется стандартная функция

void *malloc( size_t size );

В неё передаётся size - количество байт, которое нужно

выделить. Если память выделяется, то из malloc возвращается

адрес начала выделенного блока.

*/

void *ptr = malloc(size);

if( ptr != 0 ){

//увеличение счетчика

counter++;

}

return ptr;

}

void * SomeClass::operator new[]( size_t fullsize,char* str)

{

cout << "\n" << str << "\n";

void * ptr=malloc(fullsize);

if(ptr){

counter += fullsize / sizeof(SomeClass);

}

return ptr;

}

void SomeClass::operator delete( void* ptr)

{

cout<<"\nDelete Operator\n";

counter--;

/*

Для очистки памяти используется стандартная функция

void free( void *memblock );

Функция free очищает память,memblock - адрес начала

очищаемого участка

*/

free(ptr);

}

void SomeClass::operator delete[]( void* ptr)

{

cout<<"\nDelete [] Operator\n";

// функция _msize возвращает размер

// указанного блока памяти

counter -= _msize(ptr) / sizeof(SomeClass);

free(ptr);

}

void main()

{

/*

Вызывается

оператор new( size_t size,int val,char* str="New Operator")

на место size будет подставлен размер класса SomeClass,

2 попадет в val, а str получит значение по умолчанию т.е.

"New Operator"

*/

SomeClass *p = new(2) SomeClass;

SomeClass *r = new(3, "In New Operator") SomeClass;

cout << "\nThere are " <<

p->GetCounter() <<

" objects created dynamically\n";

// Вызывается delete

delete p;

delete r;

cout << "\nThere are " <<

SomeClass::GetCounter() <<

" objects created dynamically\n";

// new []

SomeClass *ar = new("New [] was activated") SomeClass[2];

cout << "\nThere are " <<

SomeClass::GetCounter() <<

" objects created dynamically\n";

// delete []

delete [] ar;

cout << "\nThere are " <<

SomeClass::GetCounter() <<

" objects created dynamically\n";

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]