Это означает, что вектор сохраняет выделенную память и должен выполнить конструкцию на месте (= размещение нового) объектов, помещаемых в нее. Это правильное предположение?
Да
Кроме того, означает ли это, что контейнер вручную вызывает деструктор, а не вызывает удаление?
Да
Есть ли другие предположения, которые я здесь упускаю? Означает ли это, что я могу предположить, что даже пользовательский текст, написанный новым для объекта, не может быть вызван, если я выбрал запись?
Да. Учтите, что даже в связанных списках контейнер не будет выделять экземпляр вашего типа, а скорее является шаблонной структурой, которая содержит подобъект типа. Для связанного списка это будет некоторый сложный тип, содержащий как минимум два указателя (обе ссылки) и подобъект вашего типа. Фактический тип, который выделен, - это узел , а не ваш тип.
Также имеет смысл использовать список для нового и удаления, поскольку нам не требуется гарантия непрерывной памяти.
Да, но не new
/ delete
объектов вашего типа.
Итак, такое поведение ведет к тому, как ведут себя распределители?
Я действительно не понимаю эту часть вопроса. Распределители - это классы, которые имеют набор ограничений, определенных в стандарте, которые включают как интерфейс (allocate
, deallocate
...), так и семантику (значение ==
состоит в том, что память, выделенная одним, может быть освобождена другое, любое другое состояние в классе не имеет значения).
Распределители могут создаваться и передаваться в контейнеры по разным причинам, включая эффективность (если вы выделяете только тип объекта, то вы можете реализовать небольшие распределители блоков чуть более эффективно, чем malloc
- или нет, зависит от ситуации).
Примечание по размещению новых
Мне всегда было интересно, что размещение новых - это термин, который, по-видимому, имеет два отдельных значения. С одной стороны - единственный способ построить объект на месте . Но, похоже, это также имеет совершенно другое значение: создайте этот объект, получая память из пользовательского распределителя .
На самом деле существует одно значение размещения нового , которое не имеет ничего общего с созданием на месте . Первый - это случай второго, где распределитель предоставляется реализацией (компилятором), как определено в 18.4.1.3, и не может быть перегружен. Эта конкретная версия перегруженного распределителя ничего не делает, кроме как возвращает аргумент (void*
), чтобы new-expression могло передать его в конструктор и создать объект в памяти (не), выделенной размещение новой версии, которая была вызвана.