Среда, 08.01.2025, 20:58
Главная Регистрация RSS поиск
Приветствую Вас, Гость
Меню сайта
Категории раздела
HTML [44]
Visual C++ и MFC [21]
c++ [78]
php [19]
Javascript [15]
C# [51]
загрузки [0]
XNA [10]
создание игр с помощью xna
Наш опрос
Каким языком программирования вы увлекаетесь
Всего ответов: 2420
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Реклама
Главная » Статьи » c++

Перегрузка операторов 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";
}
Категория: c++ | Добавил: slava (30.05.2011)
Просмотров: 7886 | Рейтинг: 5.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]