Я пытался написать определяемый пользователем объект с помощью std :: vector.
Я читал, что для классов, определяемых пользователем, если конструктор копирования и оператор присваивания являются общедоступными, то только один может вставить его объект в контейнер STL.
Это происходит по двум причинам:
что вы имеете в виду под «копией» против «фактического объекта»? Объекты в контейнерах находятся являются фактическими объектами, и если вы хотите, можете построить их на месте. Просто так случается, что поскольку контейнеры хранят значения (не ссылки или указатели), они нужно делают копию, когда вы нажимаете значение
Итак, если элемент не был скопирован; как бы вы отодвинули элемент local-to-loop без UB?
рассмотрите этот чрезвычайно упрощенный "контейнер": struct single_int { int x; single_int(int y): x(y) {} }; нет способа заставить его хранить int, который вы ему передали, но он хранит копию, потому что он управляет своими собственными ресурсами
возможно, на этот вопрос можно будет правильно ответить, если вы объясните, как, по вашему мнению, должно работать «хранить реальный объект вместо копии», потому что в настоящее время неясно, что вы имеете в виду под этим
Вы можете хранить (умные) указатели на объекты, построить их на месте внутри контейнера, std::move их в контейнер, или вставлять их копии. Это все зависит от вас.
FWIW, начиная с C++, вы можете напрямую создавать объекты в контейнерах, и когда они растут (если применимо), они будут перемещать их, а не копировать, пока объект nothrow перемещается.
Скопированный объект *является* объект. Нет никакой разницы между скопированным объектом и «настоящим». В самом деле, что составляет объект определено в зависимости от того, что делают его конструкторы копирования и операторы присваивания. Это отличается от Java или Python, где имя, относящееся к объекту, ссылается на него через скрытый указатель. Если вам нужна такая семантика, вы можете использовать ссылки и или указатели. См. «Unique_pointer» и «shared_pointer».





Стандартные контейнеры в C++ выделяют память, которой они управляют. Если ваша программа создает объект, то этот объект находится в другом месте памяти, поэтому, чтобы быть частью контейнера, копия создается в памяти контейнера.
Вместо копирования можно было бы выполнить перемещение, но во многих случаях это было бы не более эффективно, а иногда даже было бы довольно неудобно.
Хорошее решение избежать копирования - создать объект прямо в контейнере с помощью поставить-функций.
Что касается роста вектора, поскольку возможно, что новый вектор должен находиться по другому адресу памяти, а память содержит объекты, их нужно перемещать или копировать. Этот ответ показывает, как можно заставить вектор перемещаться при изменении размера.
Фактически, начиная с C++ 11 push_back std :: vector также может принимать значения r. Таким образом, возможно перемещение значений в дополнение к возможности добавления копий к вектору.
Семантика значений - ключевой момент контейнера C++.