Люди, как сделать проще, не переписывая всю программу.
Есть иерархия классов. В самом низу есть класс
class F
{
D* d;
E* e;
public:
F(someparam param)
{
d=new D(somefunction_d(param));
e=new E(somefunction_e(param));
.............
}
};
Аналогичная ситуация и для классов D и E: они в своих конструкторах вызывают new A() и new B() соответственно. Ну и чтобы было совсем весело, классы A и B выделяют какие-то буфера для своих нужд.
Теперь, есть необходимость создать тучу объектов класса F, причем известно, что убиваться они будут все одновременно. Меня такая нагрузка на стандартный распределитель не обрадовала, и я написал свой "супер-пупер распределитель" MyCoolPool, который хватает память большими блоками (скажем, по 64К), из них выделяет память, по мере надобности запрашивает еще блоки, а потом по команде FreeAll() все выделенные блоки возвращает системе. Т.е. даже не надо вызывать delete для каждого объекта, все убивается одним махом. Все вроде бы здорово, если бы было так просто.
Вопрос: как сделать так, чтобы, если при создании объекта класса F память выделялась из SomePool, то и все входящие в него new тоже выделяли бы память для себя из того же SomePool? Т.е. например, я завожу класс F_IN_POOL и у него определяю operator new (size_t n, MyCoolPool* pool)
class F_IN_POOL : public F
{
F_IN_POOL(someparam param) : F (param) {};
void* operator new(size_t n, MyCoolPool* pool) {return pool->Alloc(n);};
};
Но как сделать так, чтобы все new, которые встретятся при создании объекта класса F_IN_POOL (это new D(..) и new E (...) в конструкторе F(), а в них new A(...) и new B(...)) автоматически "редиректились" в pool? Я не нашел такого средства. Переписывать всю иерархию уж больно муторно (я вот 4 дня потратил и переписал примерно половину
). Есть ли универсальное решение этой проблемы?
Глобальный new(size_t n, MyCoolPool* pool) тоже вробе бы не поможет, т.к. нужно будет модифицировать всю иерархию и в каждом конструкторе явно писать, что каждый new теперь относится к pool, а для этого нужно будет pool передавать конструктору в качестве переметра. Это чревато ошибками, т.к. пулов в системе будет несколько, и ситуация
f_ptr=new(pool_1)F_IN_POOL(someparam, pool_2)
приведет сами понимаете к чему.
Allocator тут тоже по-моему не пройдет из-за тех же нескольких пулов в системе, а код раздувать не хочется (ведь, насколько я понимаю, при инстанцировании шаблона на каждый пул будет сгенерирован свой класс со своим кодом; дублировать довольно большой объем кода только из-за того, что есть разные pool-ы не хочется). Или я чего-то не понимаю в аллокаторах?
В общем, жду предложений, как выйти из этой ситуации. Буду благодарен.
On Sun, 11 Dec 2005 23:06:00 +0200, programmater <34509@users.rsdn.ru> wrote:
> Люди, как сделать проще, не переписывая всю программу.
> Есть иерархия классов. В самом низу есть класс
>
>
> > class F
> {
> D* d;
> E* e;
> public:
> F(someparam param)
> {
> d=new D(somefunction_d(param));
> e=new E(somefunction_e(param));
> .............
> }
> };
>
> Аналогичная ситуация и для классов D и E: они в своих конструкторах вызывают new A()
зачем переписивать, я би сделал небольшой такой класик, и переопределил в нем new для того штоби он брал память из нужного пула, и породил от етого класа все которые должни в етом пуле жить
ну а если нужно несколько пулов — то несколько класов ....
а для варианта где класы выделяют буфера — если ето класы — их также поробить от нужного базового, или влять их в клас если ето легко, ну или же явно писать плейсмент new ...
Posted via RSDN NNTP Server 1.9