2016-02-23 2 views
3

От en.cppreference.comshared_ptr и unique_ptr за исключением

Типичное использование станд :: unique_ptr включают в себя:

  • обеспечения безопасности исключений для классов и функций, которые обрабатывают объекты с динамической жизни, по гарантированию удаление на обоих нормальных выходах и выходах за исключением

  • передача собственности уникального владельца D объекты с динамической жизнью в функций

  • приобретающих собственность однозначно принадлежащие объекты с динамической жизнью из функций

  • как тип элемента в ходу-зависимых контейнеры, такие как станд :: вектор, который удерживать указатели на объекты с динамическим распределением (например, если полиморфное поведение желательно)

Я заинтересован в первом пункте.

Не указано для shared_ptr на cppreference.com. Я не могу найти сценарий, когда shared_ptr не удаляется при вызове исключения. Может ли кто-нибудь объяснить, существуют ли такие возможности?

+0

Цикл на графике. – user4581301

+0

@ user4581301: Но это не проблема, связанная с исключением, не так ли? даже если это не исключение, это может привести к проблеме? – InQusitive

+0

Нет, но это пример того, почему вы не можете гарантировать период удаления. – user4581301

ответ

3

Давайте посмотрим на пример, как std::unique_ptr может быть использован для обеспечения безопасности исключений:

someclass *ptr = new someclass; 
... 
delete ptr; // in case of exception we have problem 

так что вместо этого мы должны использовать:

std::unique_ptr<someclass> ptr = std::make_unique<someclass>(); 
... // no problem 

простой, безопасный и нет накладных расходов.

Так можно использовать shared_ptr, чтобы обеспечить безопасность исключений? Да, оно может. Но это не должно, поскольку оно предназначено для разных целей и будет иметь излишние накладные расходы. Поэтому он не упоминается как инструмент для таких случаев, но это не означает, что он не будет удалять принадлежащий ему объект, если он является единственным владельцем.

+0

Где эти накладные расходы случаются? Потому что make_shared <> доступен? \t Поскольку все shared_ptr находятся внутри стеков, когда происходит сброс стека, все должны выйти из области видимости, не так ли? – InQusitive

+1

@InQuitive атомный (потенциально блокирующий) приращение/уменьшение общего счетчика (ов). Накладные расходы памяти для блока управления. Доступ к стираемому стирателю. –

+1

@InQusitive, 'shared_ptr' является ** способом ** более сложным объектом, чем' unique_ptr', с более тяжелыми операциями в его конструкторе и деструкторе. Например, 'shared_ptr' делает ** атомный ** декремент в его деструкторе - длительная операция - в то время как unique_ptr просто вызывает deleter. – SergeyA

3

Как следует из названия, std::shared_ptr делится на указатель. Если выбрано исключение и область действия оставлена, общий указатель будет уничтожен, но если есть еще один std::shared_ptr где-то копия, то основной указатель не будет удален, а вместо этого только счетчик ссылок будет уменьшен.

Именно поэтому они не могут гарантировать, что удаление произойдет. Поскольку std::unique_ptr является уникальным гарантия может быть предоставлена, поскольку мы знаем, что она единственная, удерживающая указатель.

+0

Но каждый shared_ptr выйдет за пределы области действия и будет уменьшать счет, не так ли? – InQusitive

+0

Поскольку shared_ptr находится внутри стека, когда происходит сброс стека, все должны выйти из области видимости, не так ли? – InQusitive

+0

@InQuitive да, это уменьшало бы счет. 'shared_ptr' исключение является безопасным в том же смысле' unique_ptr'. Он просто не предназначен для использования __just__ для обеспечения безопасности исключений. –