Подтвердить что ты не робот

Умные указатели в контейнере типа std::vector?

Я изучаю умные указатели (std::auto_ptr) и просто читаю здесь и здесь, что интеллектуальные указатели (std::auto_ptr) не должны помещаться в контейнеры (т.е. std::vector), потому что даже большинство компиляторов не будут жаловаться, и это может показаться правильным. Не существует правила, согласно которому интеллектуальные указатели не будут копироваться внутри (например, классом vector) и передать его право собственности, тогда указатель станет NULL. В конце концов, все будет испорчено.

В действительности, как часто это происходит?

Иногда у меня есть векторы указателей, и если в будущем я решил, что хочу иметь вектор умных указателей, какие бы мои варианты?

Я знаю библиотеки С++ 0x и Boost, но на данный момент я предпочел бы придерживаться подхода STL.

4b9b3361

Ответ 1

Да, вы действительно не можете использовать std::auto_ptr со стандартными контейнерами. std::auto_ptr копии не эквивалентны, и поскольку стандартным контейнерам (и алгоритмам) разрешено копировать свои элементы по своему усмотрению, это закручивает вещи вверх. То есть операция копирования a std::auto_ptr имеет значение, отличное от простой копии объекта: это означает передачу права собственности.

Ваши варианты:

  • Используйте Boost Smart Pointers library. Это, возможно, ваш лучший вариант.
  • Используйте примитивные указатели. Это быстро и безопасно, если вы правильно управляете указателями. Время от времени это может быть сложно. Например, вам придется решать (избегать) проблемы с двойным удалением самостоятельно.
  • Используйте свой собственный указательный интеллектуальный указатель. Это было бы глупо; используйте Ускоренную Ускоренную Установку.

Ответ 2

Проблема, которую вы имеете в виду, касается auto_ptr, поскольку она перемещает право собственности на копию. shared_ptr и unique_ptr отлично работают с контейнерами.

Ответ 3

Любой тип, который вы используете со стандартным шаблоном контейнера, должен соответствовать требованиям для этого контейнера. В частности, тип должен удовлетворять требованиям для типов CopyConstructible и Assignable.

Многие интеллектуальные указатели удовлетворяют этим требованиям и могут использоваться со стандартными контейнерами, но std::auto_ptr не является одним из них, потому что копии std::auto_ptr не эквивалентны источнику, из которого они были созданы или назначены.

Хотя некоторые реализации стандартного контейнера могут работать с auto_ptr в некоторых ситуациях, опасно полагаться на такие детали реализации.

Ответ 4

теоретически вы можете использовать std::auto_ptr с контейнерами STL, если вы полностью понимаете их внутреннюю реализацию и не делаете ничего, что может потерять собственность auto_ptr, но практически гораздо безопаснее использовать контейнеры с необработанными ptrs.

" В действительности, как часто это происходит? "- очень опасный вопрос сам по себе. в первую очередь, STL - это не стандартная реализация, их много. Каждый из них может реализовывать контейнеры по-разному, поэтому ваш высоконастроенный код, чтобы избежать использования всех" auto_ptr в контейнерах ", может привести к переходу на другую реализацию STL. Кроме того, ваше обслуживание кода будет очень сложным, любое правильно выглядящее изменение вашего кода может сломать вашу программу. как вы можете это вспомнить или заставить других сопровождающих помнить? ввод предупреждений в любом месте, где могут произойти такие изменения? невозможно.

так что вывод: это просто плохая идея, которая приносит только головную боль.

Ответ 5

Для классов, у которых есть элемент данных auto ptr, у меня всегда есть метод clone, который возвращает новый auto ptr. Затем я реализую метод присваивания и конструктор копирования, который вызывает метод clone (и никогда не является оператором присваивания по умолчанию для auto ptr). Таким образом, вы можете безопасно использовать класс в контейнерах STL.