Это означает, что вектор сохраняет выделенную память и должен выполнять построение на месте (= размещение нового) объектов, помещаемых в него. Верно ли это предположение?
да
Кроме того, означает ли это, что контейнер вручную вызывает деструктор, а не вызывает удаление?
да
Есть ли какие-либо другие предположения, которые мне здесь не хватает? Означает ли это, что я могу предположить, что даже специально написанное новое для объекта не может быть вызвано, если я решу написать?
да. Учтите, что даже в связанных списках контейнер будет выделять не экземпляр вашего типа, а шаблонную структуру, содержащую подобъект типа. Для связанного списка это будет некоторый сложный тип, содержащий как минимум два указателя (обе ссылки) и подобъект вашего типа. На самом деле выделяемый тип — это node, а не ваш тип.
Также для списка имеет смысл использовать new и delete, поскольку нам не нужна гарантия непрерывной памяти.
Да, но не new
/delete
объекты вашего типа.
Итак, является ли такое поведение тем, что определяет поведение аллокаторов?
Я не очень понимаю эту часть вопроса. Распределители — это классы, которые имеют набор ограничений, определенных в стандарте, которые включают как интерфейс (allocate
, deallocate
...), так и семантику (значение ==
заключается в том, что память, выделенная для одного, может быть освобождена другим, любое другое состояние в классе не имеет значения).
Распределители могут быть созданы и переданы в контейнеры по разным причинам, включая эффективность (если вы выделяете только тип объекта, вы можете реализовать небольшие распределители блоков немного более эффективно, чем malloc
- или нет, зависит от ситуации) .
Примечание о новых местах размещения
Мне всегда было интересно, что термин placement new имеет два разных значения. С одной стороны, это единственный способ создания объекта на месте. Но, кажется, у него есть и совершенно другое значение: создать этот объект, получающий память из пользовательского распределителя.
На самом деле существует единственное значение placement new, которое не имеет ничего общего с созданием in-place. Первый — это просто случай второго, когда распределитель предоставляется реализацией (компилятором), как определено в 18.4.1.3, и не может быть перегружен. Эта конкретная версия перегруженного распределителя абсолютно ничего не делает, кроме как возвращает аргумент (void*
), чтобы новое выражение могло передать его в конструктор и создать объект в памяти (не), выделенной < em>разместить новую версию, которая была вызвана.
person
David Rodríguez - dribeas
schedule
14.03.2011