Является единственным различием между shared_ptr и scoped_ptr, которое
scoped_ptr не имеет конструктора копирования, а shared_ptr имеет его?
Разница более фундаментальная, чем эта; это связано с тем, как умные указатели владеют объектом, на который он указывает. Что отличает умные указатели от тупых указателей, так это то, что концепция владения является ключевым компонентом их функций. Семантика владения - это то, что отличает разные виды умных указателей.
Поскольку умные указатели «владеют» тем, на что они указывают, они могут делать полезные вещи, такие как удаление объектов, когда умные указатели исчезают (это возможно благодаря использованию только правил языка; не требуется никакой магии компилятора). Таким образом, управление памятью в C ++ может быть почти автоматическим (несмотря на все заявления об обратном, в современном C ++ очень мало ручного управления памятью).
shared_ptr
реализует подсчет ссылок
семантика для
управление памятью. Несколько shared_ptr
s могут владеть одним объектом.
shared_ptr
уход не обязательно удаляет объект
указывает на то, что может быть другой shared_ptr
, владеющий
объект. Последний shared_ptr
, который владеет объектом и уходит, будет
удалить принадлежащий ему объект.
scoped_ptr
реализует семантику исключительной собственности. Только один
scoped_ptr
может владеть любым одним объектом. Когда scoped_ptr
уходит,
он всегда будет удалять принадлежащий ему объект (потому что есть только один
владелец). Обычно он используется как легкий механизм RAII для
объекты, размещенные в свободном магазине.
Версии массива (shared_array
и scoped_array
) имеют практически одинаковую семантику, но предназначены специально для массивов, например они используют delete[]
вместо delete
, реализуют оператор индекса массива и т. д.
shared_ptr
и shared_array
также позволяют указать пользовательское средство удаления, если поведение по умолчанию delete
не подходит для объекта. scoped_ptr
и scoped_array
не имеют этой способности, поскольку они довольно легкие по сравнению с shared_ptr
и shared_array
.
В C ++ 11, самой новой и текущей версии C ++, есть также unique_ptr
, который аналогичен scoped_ptr
, за исключением того, что вы можете передать право собственности на объект другому unique_ptr
. В C ++ 03, более старой, но более широко поддерживаемой версии C ++, есть auto_ptr
, что эквивалентно unique_ptr
, за исключением того, что его было легко использовать небезопасным образом случайно (именно поэтому он устарел в C +) +11).
Должен ли я использовать scoped_ptr вместо shared_ptr всегда, когда объект
не вызывает конструктор копирования?
То, что вы выберете, не зависит от наличия конструктора копирования, поскольку shared_ptr
и scoped_ptr
не требуют, чтобы объект был копируемым. Вы выбираете один в зависимости от требуемой семантики владения. Если у объекта будет несколько владельцев, вы используете shared_ptr
. Если у объекта будет только один владелец, и существование объекта длится только в области видимости, используйте scoped_ptr
(отсюда и название scoped_ptr
).
Я также не понимаю идею общего / объемного массива. Разве я не могу просто
использовать вместо него std :: vector?
std::vector
не реализует семантику подсчета ссылок, как shared_array
. std::vector
больше похоже на scoped_array
, но может быть скопировано. Когда вы копируете std::vector
, вы также копируете все содержащиеся в нем элементы. Это не относится к scoped_array
. std::vector
также имеет функции, которые позволяют вам манипулировать и проверять его содержимое (например, push_back
, insert
, erase
и т. Д.), Но гораздо тяжелее, чем scoped_array
.