Различия между уникальным 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_ptr
unique_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, то сохраненный объект будет уничтожен.