В C ++ 2003 модель распределителя нарушена, и на самом деле не существует правильного решения.В C ++ 2011 модель распределителя была исправлена, и у вас могут быть распределители для каждого экземпляра, которые распространяются вплоть до содержащихся объектов (если, конечно, вы не решите заменить их).Как правило, для того, чтобы это было полезно, вы, вероятно, захотите использовать динамически полиморфный тип распределителя, который не требуется по умолчанию std::allocator<T>
(и, как правило, я ожидаю, что он не будет динамически полиморфным, хотя это может быть лучшим вариантом реализации).Однако [почти] все классы в стандартной библиотеке C ++, которые выполняют выделение памяти, являются шаблонами, которые принимают тип распределителя в качестве аргумента шаблона (например, IOStreams являются исключением, но обычно они не выделяют какой-либо интересный объем памяти для гарантии добавления поддержки распределителя).).
В нескольких ваших комментариях вы настаиваете, что распределители должны быть глобальными: это определенно не правильно.Каждый тип, связанный с распределителем, хранит копию данного распределителя (по крайней мере, если у него есть какие-либо данные уровня экземпляра; если нет, то нет ничего для хранения, как, например, в случае с распределителем по умолчанию, использующим operator new()
иoperator delete()
).Это фактически означает, что механизм выделения, данный объекту, должен оставаться неизменным, пока есть активный распределитель, использующий его.Это может быть выполнено с использованием глобального объекта, но также может быть выполнено с использованием, например, подсчета ссылок или связывания распределителя с объектом, содержащим все объекты, которым он присвоен.Например, если каждый «документ» (например, XML, Excel, Pages, любой файл структуры) передает распределитель своим членам, распределитель может жить как член документа и уничтожаться при уничтожении документа после уничтожения всего его содержимого.,Эта часть модели распределителя должна работать с классами до C ++ 2011, если они также принимают аргумент распределителя.Однако в классах до C ++ 2011 распределитель не будет передаваться содержащимся объектам.Например, если вы назначите распределитель для std::vector<std::string>
, то версия C ++ 2011 создаст std::string
s, используя распределитель, данный std::vector<std::string>
, соответствующим образом преобразованный для работы с std::string
s.Этого не произойдет с распределителями до C ++ 2011.
Чтобы фактически использовать распределители в подсистеме, вам нужно будет эффективно передавать их как явно в качестве аргумента для ваших функций и / или классов, так и неявнопосредством объектов с распределителем, которые служат контекстом.Например, если вы используете какой-либо из стандартных контейнеров как [часть] передаваемого контекста, вы можете получить используемый распределитель, используя метод get_allocator()
.