Мир, в котором живет Бьярне, очень ... академичен, из-за отсутствия лучшего термина. Если ваш код может быть спроектирован и структурирован так, что объекты имеют очень преднамеренные реляционные иерархии, так что отношения владения являются жесткими и несгибаемыми, код перемещается в одном направлении (от высокого уровня к низкому уровню), и объекты общаются только с теми, кто ниже. иерархии, то вы не найдете особой необходимости shared_ptr
. Это то, что вы используете в тех редких случаях, когда кто-то должен нарушать правила. Но в противном случае вы можете просто вставить все в vector
s или другие структуры данных, которые используют семантику значений, и unique_ptr
s для вещей, которые вы должны выделять отдельно.
Хотя это великий мир для жизни, это не то, чем ты можешь заниматься все время. Если вы не можете организовать свой код таким образом, потому что дизайн системы, которую вы пытаетесь создать, означает, что это невозможно (или просто крайне неприятно), тогда вы обнаружите, что вам все больше и больше нужно совместно владеть объектами. ,
В такой системе держать голые указатели ... не совсем точно, но это вызывает вопросы. Самое замечательное в том, shared_ptr
что он предоставляет разумные синтаксические гарантии о времени жизни объекта. Это может быть сломано? Конечно. Но люди могут и const_cast
вещи; базовый уход и питание shared_ptr
должны обеспечивать разумное качество жизни для выделенных объектов, права собственности на которые должны быть разделены.
Тогда есть weak_ptr
s, которые нельзя использовать в отсутствие a shared_ptr
. Если ваша система жестко структурирована, вы можете хранить голый указатель на некоторый объект, будучи уверенным в том, что структура приложения гарантирует, что указанный объект переживет вас. Вы можете вызвать функцию, которая возвращает указатель на некоторое внутреннее или внешнее значение (например, найти объект с именем X). В правильно структурированном коде эта функция будет доступна вам только в том случае, если время жизни объекта будет гарантированно превышать ваше; таким образом, хранение этого голого указателя в вашем объекте - это хорошо.
Поскольку такой жесткости не всегда удается достичь в реальных системах, вам нужен какой-то способ разумного обеспечения срока службы. Иногда вам не нужно полное владение; иногда вам просто нужно знать, когда указатель плох или хорош. Вот где weak_ptr
приходит. Были случаи, когда я мог использовать unique_ptr
или boost::scoped_ptr
, но я должен был использовать, shared_ptr
потому что мне специально нужно было дать кому-то «изменчивый» указатель. Указатель, время жизни которого было неопределенным, и они могли запрашивать, когда этот указатель был уничтожен.
Безопасный способ выжить, когда состояние мира неопределенно.
Может ли это быть сделано с помощью вызова некоторой функции, чтобы получить указатель, а не через weak_ptr
? Да, но это может быть легко сломано. Функция, которая возвращает голый указатель, не имеет возможности синтаксически предлагать пользователю не делать что-то вроде сохранения этого указателя в долгосрочной перспективе. Возвращение shared_ptr
также делает слишком простым его хранение и потенциально продлевает срок службы объекта. Возвращение, weak_ptr
однако, убедительно говорит о том, что хранение полученной shared_ptr
вами информации lock
является ... сомнительной идеей. Это не помешает вам сделать это, но ничто в C ++ не мешает вам взломать код. weak_ptr
обеспечивает некоторое минимальное сопротивление от выполнения естественных вещей.
Это не значит, что shared_ptr
нельзя злоупотреблять ; это конечно может. Прежде всего unique_ptr
, было много случаев, когда я просто использовал a, boost::shared_ptr
потому что мне нужно было передать указатель RAII или поместить его в список. Без ходовой семантики и unique_ptr
, boost::shared_ptr
был единственным реальным решением.
И вы можете использовать его в местах, где это совершенно не нужно. Как указано выше, правильная структура кода может исключить необходимость использования shared_ptr
. Но если ваша система не может быть структурирована как таковая и все еще делать то, что ей нужно, она shared_ptr
будет весьма полезна.