Различия между уникальным ptr и общим ptr [дубликат]
Возможные Дубликаты:
pimpl: shared_ptr или unique_ptr
смарт указатели (boost) объяснил
кто-нибудь может объяснить различия между shared_ptr и unique_ptr?
4 ответа:
оба этих класса являются интеллектуальными указателями, что означает, что они автоматически (в большинстве случаев) будут освобождать объект, на который они указывают, когда этот объект больше не может ссылаться. Разница между ними заключается в том, сколько разных указателей каждого типа может ссылаться на ресурс.
при использовании
unique_ptr, может быть не более одногоunique_ptrуказывая на какой-либо один ресурс. Когда этоunique_ptrуничтожается, ресурс автоматически восстанавливается. Потому что там можно только одинunique_ptrна любой ресурс, любая попытка сделать копиюunique_ptrвызовет ошибку времени компиляции. Например, этот код является незаконным:,unique_ptr<T> myPtr(new T); // Okay unique_ptr<T> myOtherPtr = myPtr; // Error: Can't copy unique_ptrunique_ptrможет быть двигался использование новой семантики перемещения:unique_ptr<T> myPtr(new T); // Okay unique_ptr<T> myOtherPtr = std::move(myPtr); // Okay, resource now stored in myOtherPtrаналогично, вы можете сделать что-то вроде этого:
unique_ptr<T> MyFunction() { unique_ptr<T> myPtr(/* ... */); /* ... */ return myPtr; }эта идиома означает " Я возвращаю вам управляемый ресурс. Если вы явно не фиксируете возвращаемое значение, то ресурс будет очищенный. Если вы это сделаете, то теперь у вас есть исключительное право собственности на этот ресурс."Таким образом, вы можете думать о
unique_ptrкак более безопасная, лучшая замена дляauto_ptr.
shared_ptr, С другой стороны, позволяет нескольким указателям указывать на данный ресурс. Когда самый последнийshared_ptrчтобы ресурс был уничтожен, ресурс будет освобожден. Например, этот код совершенно легален:shared_ptr<T> myPtr(new T); // Okay shared_ptr<T> myOtherPtr = myPtr; // Sure! Now have two pointers to the resource.внутри
shared_ptrиспользует ссылка подсчет чтобы отслеживать, сколько указателей ссылаются на ресурс, поэтому вам нужно быть осторожным, чтобы не вводить никаких ссылочных циклов.короче:
- использовать
unique_ptrкогда вы хотите один указатель на объект, который будет восстановлен, когда этот единственный указатель будет уничтожен.- использовать
shared_ptrесли вы хотите несколько указателей на один и тот же ресурс.надеюсь, что это помогает!
unique_ptrЭто легкий умный указатель выбора, если у вас просто есть динамический объект где-то, для которого один потребитель имеет единственную (следовательно, "уникальную") ответственность-возможно, класс-оболочка, который должен поддерживать некоторый динамически выделенный объект.unique_ptrимеет очень мало накладных расходов. Он не копируется,но перемещается. Его тип иtemplate <typename D, typename Deleter> class unique_ptr;, Так что это зависит от два параметры шаблона.
unique_ptrтакжеauto_ptrхотел чтобы быть в старом C++, но не мог из-за ограничений этого языка.
shared_ptrС другой стороны, это совсем другое животное. Очевидное различие заключается в том, что у вас может быть много потребителей, разделяющих ответственность за динамический объект (следовательно, "общий"), и объект будет уничтожен только тогда, когда все общие указатели исчезнут. Кроме того, вы можете наблюдать слабых ссылок который будет разумно проинформирован, если общий указатель, за которым они следуют, имеет исчез.внутри
shared_ptrимеет гораздо больше происходит: есть счетчик ссылок, который обновляется атомарно, чтобы разрешить использование в параллельном коде. Кроме того, существует множество распределений, один для внутреннего бухгалтерского учета "контрольный блок управления", а другой (часто) для фактического объекта-члена.но есть еще одна большая разница: общий тип указателей всегда
template <typename T> class shared_ptr;, и это несмотря на то, что вы можете инициализировать его с помощью пользовательских удалителей и С пользовательских распределителей. Удалитель и распределитель отслеживаются с помощью стирания типа и отправки виртуальной функции, что добавляет к внутреннему весу класса, но имеет огромное преимущество, что различные виды общих указателей типаTвсе совместимы, независимо от деталей удаления и распределения. Таким образом, они действительно выражают концепцию "совместной ответственности заT" не обременяя потребителя подробности!и
shared_ptrиunique_ptrпредназначены для передачи по значению (с очевидным требованием подвижности для уникального указателя). Ни один из них не должен заставлять вас беспокоиться о накладных расходах, так как их мощность действительно поразительна, но если у вас есть выбор, предпочитайтеunique_ptrиshared_ptrесли вам действительно нужна общая ответственность.
unique_ptr не
это умный указатель, который владеет объектом исключительно.shared_ptr
является интеллектуальным указателем для совместного владения. Это какcopyableиmovable. Один и тот же ресурс может принадлежать нескольким экземплярам интеллектуальных указателей. Как только последний интеллектуальный указатель, владеющий ресурсом, выйдет из области видимости, ресурс будет освобожден.
при обертывании указателя в
unique_ptrвы не можете иметь несколько копийunique_ptr. Элементshared_ptrсодержит счетчик ссылок, который подсчитывает количество копий сохраненного указателя. Каждый раз, когдаshared_ptrкопируется, этот счетчик увеличивается. Каждый раз, когдаshared_ptrразрушается, этот счетчик уменьшается. Когда этот счетчик достигает 0, то сохраненный объект будет уничтожен.