Когда их стоит использовать
Умные указатели? - задан сегодня утром.
Нужно ли, например, объявлять массив при помощи std::unique_ptr и т.д.
В большинстве случаев лучше std::array для массивов размера, известного во время компиляции, и std::vector - если размер становится известен только при выполнении программы. Исключение - необходимость взаимодействия с кодом, использующим обычные указатели на массивы (в частности, с Сишным кодом).
и какой из них?
std::unique_ptr подразумевает одного владельца в один момент времени, и переход владения от одного умного указателя к другому (ownership transfer). std::shared_ptr использует подсчет ссылок, чтобы у объекта было несколько владельцев. Объект будет уничтожен, когда последний shared_ptr, указывающий на этот объект, будет уничтожен.
Разумеется, и та и другая стратегия работает только в умных указателях. Если вы скопируете содержимое умного указателя в обычный, и затем объект будет удален умным указателем, то обычный указатель продолжит указывать на тот же адрес в памяти. Это очевидная вещь, но именно на нее все напарываются поначалу.
Отдельно добавлю, что unique_ptr это
один из способов моделирования композиции объектов (когда умирает владеющий объект, умирают и те, которыми он владеет), а shared_ptr - агрегации (если владеющий объект умирают, те, которыми он владел, продолжают жить, пока они нужны кому-то еще).