С++ - язык, который изучается постепенно.ГЛАВА 15. Пространства объектов
                   Справочники Всё для создания сайта

Ссылки


Home
Бизнес
Справочники
Советы







Материалы книги получены с http://www.itlibitum.ru/

Пространства объектов

Половины представлены в виде пространств памяти для создания объектов. Класс HalfSpace

изображает одну половину, а Space - всю память, видимую клиентам.

Класс HalfSpace

Каждая половина по отдельности выглядит как обычное пространство памяти со специализированной функцией Allocate(). Парная функция Deallocate() не понадобится.

class HalfSpace {

private:

unsigned long next_byte; // Следующий выделяемый байт

unsigned char bytes[HALFSIZE];

public:

HalfSpace() : next_byte(0) {}

void* Allocate(size_t size);

void Reinitialize() { next_byte = 0; }

};

void* HalfSpace::Allocate(size_t size)

{

// Выровнять до границы слова

size = ROUNDUP(size);

if (next_byte + size >= HALFSIZE)

return NULL; // Не хватает памяти

void* space = &bytes[next_byte];

next_byte += size;

return space;

}

Класс Space

Общий пул представляет собой совокупность двух половин. Он также имеет функцию  Allocate(), которая в обычных ситуациях просто поручает работу активной половине. Если в активной половине не найдется достаточно памяти, происходит переключение половин и копирование активных объектов в другую половину функцией Swap(). Эта схема основана на предыдущем материале - специализированном пуле VoidPtr со средствами перебора.

class Space {

private:

HalfSpace A, B;

HalfSpace* active;

HalfSpace* inactive;

void Swap(); // Переключить активную половину, скопировать объекты

public:

Space() : active(&A), inactive(&B) {};

void* Allocate(size_t size);

};

void* Space::Allocate(size_t size)

{

void* space = active->Allocate(size);

if (space != NULL) return space;

Swap();

Space = active->Allocate(size);

if (space == NULL)

// Исключение - нехватка памяти

return space;

}

void Space::Swap()

{

if (active == &A)

{

active = &B;

inactive = &A;

}

else

{

active = &A;

inactive = &B;

}

active->Reinitialize();

// Перебрать все VoidPtr и найте активные объекты

VoidPtrIterator* iterator = VoidPtr::pool->iterator();

while (iterator->More())

{

VoidPtr* vp = iterator->Next();

if (vp->address >= inactive &&

vp->address < inactive + sizeof(*inactive))

{

void* new_space = active->Allocate(vp->size);

if (new_space == NULL)

// Исключение - нехватка памяти

memcpy(new_space, vp->address, vp->size);

vp->address = new_space;

}

}

delete iterator;

}

Все существенное происходит в цикле while функции Space::Swap(). Каждый объект в предыдущей, ранее активной половине копируется в новую активную половину. Вскоре вы поймете, зачем мы проверяем, принадлежит ли адрес старой половине.

Оператор new

Конечно, у нас появляется перегруженный оператор new, который использует эту структуру.

void* operator new(size_t size, Space* space)

{

return space->Allocate(size);

}

Ведущие указатели

Наконец, ведущие указатели должны использовать это пространство при создании объектов.

template <class Type>

class BMP : public VoidPtr {

private: // Запретить копирование и присваивание указателей

BMP(const MP<Type>&) {}

BMP<Type>& operator=(const BMP<Type>&) { return *this; }

public:

BMP() : VoidPtr(new(object_space) Type, sizeof(Type)) {}

virtual ~BMP() { ((Type*)address->Type::~Type(); }

Type* operator->() { return (Type*)address; }

};

Здесь object_space - глобальная переменная (а может быть, статическая переменная класса VoidPtr), которая ссылается на рабочее пространство Space.


Назад    Содержание    Далее    

Home  Создание сайтов  Учебник по записи CD  Справочник Web дизайнера Самоучитель IE PHP и MySQL Компьютерные сети С++ E-mail me

Copyright 2007. Климов Александр. All Right Reserved.
Hosted by uCoz