|
Программирование >> Перегруженные имена функций и идентификаторы
Краткое описание конкретной ситуации, где всё это и происходило. В некотором исследовательском центре есть биохимическая лаборатория. Есть в ней куча соответствующих анализаторов. Железки они умные, работают самостоятельно, лишь бы сунули кассету с кучей материалов и заданиями. Всякий анализатор обрабатывает материалы только определённой группы. Со всех них результаты текут по одному шлангу в центр всяческих обработок и складирования. Масса частностей, но нам они неинтересны. Суть - всякий результат есть результат биохимического анализа. Текущий потоком байт с соответствующими заголовками и всякими телами. Конкретный тип реально выяснить из первых шестнадцати байт. Максимальный размер - есть. 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 ) );
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |