Копия вставки контейнера STL C++

Я пытался написать определяемый пользователем объект с помощью std :: vector.

Я читал, что для классов, определяемых пользователем, если конструктор копирования и оператор присваивания являются общедоступными, то только один может вставить его объект в контейнер STL.
Это происходит по двум причинам:

  1. Все STL-файлы всегда хранят копию вставленных объектов, а не реальную. Итак, всякий раз, когда мы вставляем какой-либо элемент или объект в контейнер, вызывается его конструктор копирования для создания копии, а затем эта копия вставляется в контейнер.
  2. При вставке в std :: vector возможно, что перемещение хранилища происходит внутри из-за недостатка места. В таких случаях оператор присваивания будет вызываться для объектов внутри контейнера, чтобы скопировать их из одного места в другое.

почему весь контейнер STL всегда хранит копию вставленных объектов, а не саму?
I couldn't understand the reason as to why they didn't allow the storing of the actual object. what was the disadvantage?

Семантика значений - ключевой момент контейнера C++.

llllllllll 19.03.2018 13:29

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

largest_prime_is_463035818 19.03.2018 13:30

Итак, если элемент не был скопирован; как бы вы отодвинули элемент local-to-loop без UB?

UKMonkey 19.03.2018 13:32

рассмотрите этот чрезвычайно упрощенный "контейнер": struct single_int { int x; single_int(int y): x(y) {} }; нет способа заставить его хранить int, который вы ему передали, но он хранит копию, потому что он управляет своими собственными ресурсами

largest_prime_is_463035818 19.03.2018 13:35

возможно, на этот вопрос можно будет правильно ответить, если вы объясните, как, по вашему мнению, должно работать «хранить реальный объект вместо копии», потому что в настоящее время неясно, что вы имеете в виду под этим

largest_prime_is_463035818 19.03.2018 13:38

Вы можете хранить (умные) указатели на объекты, построить их на месте внутри контейнера, std::move их в контейнер, или вставлять их копии. Это все зависит от вас.

Bo Persson 19.03.2018 13:48

FWIW, начиная с C++, вы можете напрямую создавать объекты в контейнерах, и когда они растут (если применимо), они будут перемещать их, а не копировать, пока объект nothrow перемещается.

NathanOliver 19.03.2018 13:57

Скопированный объект *является* объект. Нет никакой разницы между скопированным объектом и «настоящим». В самом деле, что составляет объект определено в зависимости от того, что делают его конструкторы копирования и операторы присваивания. Это отличается от Java или Python, где имя, относящееся к объекту, ссылается на него через скрытый указатель. Если вам нужна такая семантика, вы можете использовать ссылки и или указатели. См. «Unique_pointer» и «shared_pointer».

Jive Dadson 19.03.2018 14:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
789
1

Ответы 1

Стандартные контейнеры в C++ выделяют память, которой они управляют. Если ваша программа создает объект, то этот объект находится в другом месте памяти, поэтому, чтобы быть частью контейнера, копия создается в памяти контейнера.

Вместо копирования можно было бы выполнить перемещение, но во многих случаях это было бы не более эффективно, а иногда даже было бы довольно неудобно.

Хорошее решение избежать копирования - создать объект прямо в контейнере с помощью поставить-функций.

Что касается роста вектора, поскольку возможно, что новый вектор должен находиться по другому адресу памяти, а память содержит объекты, их нужно перемещать или копировать. Этот ответ показывает, как можно заставить вектор перемещаться при изменении размера.

Фактически, начиная с C++ 11 push_back std :: vector также может принимать значения r. Таким образом, возможно перемещение значений в дополнение к возможности добавления копий к вектору.

kaba 03.01.2020 02:26

Другие вопросы по теме