std :: allocator construct / destroy против размещения new / p-> ~ T () - PullRequest
8 голосов
/ 17 марта 2009

Для моего проекта я пишу несколько контейнеров STL с нуля (у меня есть свои причины). Поскольку я так близко имитирую функциональность и интерфейсы STL, я прилагаю все усилия, чтобы придерживаться политики «если у нее такое же имя, как у стандартной конструкции, она будет максимально соответствовать стандарту».

Так что, конечно, мои контейнеры принимают распределители в качестве параметра шаблона, что очень удобно, поскольку допускает некоторые пользовательские схемы размещения. На мой вопрос.

Интерфейс std::allocator отделяет распределение памяти от построения объекта. Точно так же это отделяет освобождение от разрушения. Это имеет смысл, поскольку то, откуда вы получаете память, более или менее не имеет значения для правильного конструирования объекта в c ++.

Таким образом, есть две функции конструирования / освобождения, которые выглядят так для реализации по умолчанию (взяты прямо из книги):

void construct(pointer p, const T& val)    { new(p) T(val); }
void destroy(pointer p)                    { p->~T(); }

Как вы можете видеть, конструкция просто вызывает размещение новых, а уничтожение просто вызывает деструктор.

Есть ли какая-либо причина использовать их, просто используя новый синтаксис и синтаксис деструктора? может ли «правильный» распределитель реализовать их по-другому? Или я гарантирую, что все реализации распределителя, которые соответствуют стандарту, будут иметь методы конструирования / уничтожения, реализованные таким образом?

Более конкретно, можно ли с уверенностью сказать, что я всегда могу использовать std::uninitialized_copy и std::uninitialized_fill для конструирования элементов моих контейнеров?

Спасибо.

Ответы [ 2 ]

11 голосов
/ 17 марта 2009

Распределитель может добавлять операторы журналирования до и после строительства / разрушения, или любые другие побочные эффекты, которые он мог сделать.

Конечно, фактическая конструкция должна происходить путем вызова размещения new и деструктора, но в книге правил не говорится, что ничего другого не должно происходить в функциях конструкции / уничтожения

3 голосов
/ 17 марта 2009

Это просто, чтобы скрыть детали размещения в методе. то есть мы предоставляем API для строительства и разрушения, в будущем мы можем изменить реализацию. Теперь мы используем размещение new для выделения памяти, в будущем, если мы хотим изменить распределение, нам просто нужно изменить эти два метода.

...