Программирование >>  Перегруженные имена функций и идентификаторы 

1 ... 128 129 130 [ 131 ] 132 133 134 ... 210


Краткое описание конкретной ситуации, где всё это и происходило. В некотором исследовательском центре есть биохимическая лаборатория. Есть в ней куча соответствующих анализаторов. Железки они умные, работают самостоятельно, лишь бы сунули кассету с кучей материалов и заданиями. Всякий анализатор обрабатывает материалы только определённой группы. Со всех них результаты текут по одному шлангу в центр всяческих обработок и складирования. Масса частностей, но нам они неинтересны. Суть - всякий результат есть результат биохимического анализа. Текущий потоком байт с соответствующими заголовками и всякими телами. Конкретный тип реально выяснить из первых шестнадцати байт. Максимальный размер - есть. Ho он лишь максимальный, а не единственно возможный.

He вдаваясь в подробности принятого решения (это вынудит вдаваться в подробности задания), возникла конкретная задача при реализации - уже во время исполнения конструктора объекта конкретный тип результата анализа неизвестен. Неизвестен (соответственно) и его размер. Известен лишь размер пула для хранения некоторого количества этих объектов. Две проблемы - сконструировать объект конкретного типа в конструкторе объекта другого (обобщающего) типа и положить его на это же самое место в памяти. При этом память должно использовать эффективно, всячески минимизируя (главная проблема) фрагментацию пула, ибо предсказать время, в течение которого результат будет оставаться нужным (в ожидании, в частности, своих попутчиков от других анализаторов), невозможно. Это - не очередь (иначе всё было бы значительно проще).

Решение: от классической идиомы envelope/letter (которая сама по себе основа кучи идиом) к виртуальному конструктору с особым (либо входящим в состав, либо находящимся в дружеских отношениях) менеджером памяти. Излагается на смеси C++ и недомолвок (некритичных) в виде . . . :

class BCAR { Bio-Chemical Analysis Result

friend class BCAR MemMgr; protected:

BCAR() { /* Должно быть пусто!!! */ }



public:

BCAR( const unsigned char * ); void *operator new( size t ); void operator delete( void * ); virtual int size() { return 0; }

private:

struct {

трали-вали } header;

Это был базовый класс для всех прочих конкретных результатов анализов. У него есть свой new. Но для реализации идеи используется не дефолтовый new из C++ rtl, а используется следующее:

inline void *operator new( size t, BCAR *p ) { return p;

Именно за счёт его мы получим in place замену объекта одного класса (базового) объектом другого (производного). Раньше б1ло проще - this допускал присваивание.

Теперь - менеджер памяти.

class BCAR MemMgr {

friend BCAR;

public:

BCAR MemMgr(); void alloc( int ); void free( BCAR *, int ); BCAR *largest();

private:



Это примерный его вид. Он создаётся в единственном экземпляре:

static BCAR MemMgr MemoryManager; и занимается обслугой пула памяти под все объекты. В открытом интерфейсе у него всего три функции, назначение alloc/free любому понятно (хотя alloc в действительности ничего не аллоцирует, а делает обрезание того, что даёт largest и соответствующим образом правит списки менеджера), а largest возвращает указатель на самый большой свободный блок. В сущности, она и есть BCAR::new, которая выглядит так:

void *BCAR::operator new( size t ) { return MemoryManager.largest();

Зачем самый большой? А затем, что при создании объекта его точный тип ещё неизвестен (ибо создаваться будет через new BCAR), поэтому берём по максимуму, а потом alloc всё подправит.

Теперь собственно классы для конкретных результатов. Все они выглядят примерно одинаково:

class Phlegm: public BCAR {

friend BCAR;

private:

int size() { retrurn sizeof( Phlegm ); } struct PhlegmAnalysisBody { тут всякие его поля

PhlegmAnalysisBody body;

Phlegm( const unsigned char *data ): BCAR() { MemoryManager.alloc( size() ); ::memcpy( &body, data + sizeof( header ), sizeof( body ) );

Где тут расположен виртуальный конструктор. А вот он:

BCAR::BCAR( const unsigned char *dataStream ) {

::memcpy( &header, dataStream, sizeof( header ) );



1 ... 128 129 130 [ 131 ] 132 133 134 ... 210

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика