Эмпирическое правило
Алгоритмы, которые изменяют или манипулируют данными , не принимая на себя владение , должны воздействовать на итераторы или ссылки на данные (или их контейнер).
Например, если вы хотите найти среднее для набора значений, вы должны написать функцию, которая переводит итераторы в набор значений (или принимает контейнер по константной ссылке). То, что вы не должны делать, это передавать вектор за копией или передавать смарт-указатель.
С копированием shared_ptr
связаны накладные расходы, и сами алгоритмы всегда должны ожидать, что данные, которыми они манипулируют, переживут вычисления.
Когда использовать shared_ptr
? shared_ptr
следует использовать при написании контейнеров или других классов, которые должны удерживать часть данных в течение неизвестного периода времени. Объекты становятся собственностью, а не функциями и не алгоритмами. (Функции-члены, конечно, могут принимать shared_ptr
в качестве входных данных, но это имеет смысл делать только в том случае, если класс, которому они принадлежат, должен владеть этими данными).
А как насчет темы?
Потоки являются исключением из этого правила. Если вы начинаете новый поток, вы обязательно должны передать любые shared_ptr
s по значению. Поток может прожить неизвестное количество времени, и вам нужно убедиться, что любые данные, к которым он имеет доступ, остаются действительными до тех пор, пока поток не выйдет.
Копирование shared_ptr
намного дешевле, чем запуск потока в любом случае, поэтому его издержки минимальны.