Хорошо, для простоты, скажем, вы отслеживаете коллекцию MyFunClass
для вашего движка.Это может быть что угодно, и ваш линейный распределитель не обязательно должен отслеживать объекты однородного типа, но часто это так.В целом, при использовании пользовательских распределителей вы пытаетесь «сформировать» свои распределения памяти для разделения статических данных от динамических, редко используемых и часто используемых с целью оптимизации вашего рабочего набора и достижения локальности ссылок.
Учитывая код, который вы указали, сначала вы должны выделить свой пул памяти.Для простоты предположим, что вам нужно достаточно места для объединения 1000 объектов типа MyFunClass
.
StackAllocator sa;
sa.Init( 1000 * sizeof(MyFunClass) );
Тогда каждый раз, когда вам нужно «выделить» новый блок памяти для FunClass
, вы можете сделатьэто так:
void* mem = sa.allocUnaligned( sizeof(MyFunClass) );
Конечно, на самом деле ничего не выделяет .Все выделение уже произошло на шаге 1. Он просто помечает часть уже выделенной памяти как используемую.
Он также не создает MyFunClass
.Ваш распределитель не является строго типизированным, поэтому память, которую он возвращает, может быть интерпретирована , как вы хотите : как поток байтов;в качестве вспомогательного представления объекта класса C ++;и т.д.
Теперь, как бы вы использовали буфер, выделенный таким образом?Одним из распространенных способов является размещение нового:
auto myObj = new (mem) MyFunClass();
Итак, теперь вы создаете свой объект C ++ в том пространстве памяти, которое вы зарезервировали с помощью вызова allocUnaligned
.
(обратите внимание, чтоallocUnaligned
bit дает вам некоторое представление о том, почему мы обычно не пишем наши собственные пользовательские распределители: потому что их сложно получить до чертиков! Мы еще даже не упомянули проблемы выравнивания.)
Длядополнительные кредиты, взгляните на стеки областей действия , которые выводят подход линейного распределителя на следующий уровень.