смарт-указатели (boost) объяснил



в чем разница между следующим набором указателей? Когда вы используете каждый указатель в производственном коде, если вообще используете?



примеры будут оценены!




  1. scoped_ptr


  2. shared_ptr


  3. weak_ptr


  4. intrusive_ptr



вы используете boost в производственном коде?

640   4  

4 ответов:

основные свойства интеллектуальных указателей

это легко, когда у вас есть свойства, которые вы можете назначить каждому смарт-указателю. Есть три важных свойства.

  • нет собственности вообще
  • передачи в собственность
  • долей собственности

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

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

некоторые владельцы смарт-указателей не поддерживают ни второй, ни третий. Поэтому они не могут быть возвращены из функций или переданы в другое место. Который наиболее подходит для RAII цели, в которых интеллектуальный указатель хранится локально и просто создается, чтобы освободить объект после его выхода из области видимости.

доля собственности может быть реализована с помощью конструктора копирования. Это естественно копирует смарт-указатель, и как копия, так и оригинал будут ссылаться на один и тот же объект. Передача права собственности в настоящее время не может быть реализована в C++, потому что нет средств для передачи чего-либо от одного объекта к другому, поддерживаемых языком: Если вы пытаетесь вернуть объект из функции, происходит то, что объект копируется. Так что умный указатель, который реализует передача права собственности должна использовать конструктор копирования для реализации этой передачи права собственности. Однако это, в свою очередь, нарушает его использование в контейнерах, поскольку требования устанавливают определенное поведение конструктора копирования элементов контейнеров, которое несовместимо с этим так называемым "движущимся конструктором" поведения этих интеллектуальных указателей.

C++1x обеспечивает встроенную поддержку передачи прав собственности путем введения так называемых" конструкторов перемещения "и"операторов присваивания перемещения". Оно также поставляется с таким интеллектуальным указателем передачи собственности под названием unique_ptr.

категоризация интеллектуальных указателей

scoped_ptr - Это смарт-указатель, который не является ни переводной, ни показать. Это просто можно использовать, если вам локально нужно выделить память, но убедитесь, что она снова освобождена, когда она выходит за рамки. Но он все еще может быть заменен другим scoped_ptr, если вы хотите это сделать.

shared_ptr это умный указатель, который разделяет собственность (третий вид выше). Это ссылка подсчитывается, чтобы он мог видеть, когда последняя копия выходит из области действия, а затем освобождает управляемый объект.

weak_ptr не является владельцем смарт-указатель. Он используется для ссылки на управляемый объект (управляемый shared_ptr) без добавления счетчика ссылок. Обычно вам нужно будет получить необработанный указатель из shared_ptr и скопировать его. Но это было бы небезопасно, так как у вас не было бы способа проверить, когда объект был фактически удален. Так, weak_ptr предоставляет средства с помощью ссылки на объект, управляемый shared_ptr. Если вам нужно получить доступ к объекту, вы можете заблокировать управление им (чтобы избежать этого в другом потоке shared_ptr освобождает его во время использования объекта), а затем использовать его. Если weak_ptr указывает на уже удаленный объект, он заметит вас, создав исключение. Используя создание наиболее выгоден, когда у вас есть циклическая ссылка: подсчет ссылок не может легко справиться с такой ситуацией.

intrusive_ptr как shared_ptr, но это не сохраняет счетчик ссылок в shared_ptr, но оставляет увеличение / уменьшение счетчика для некоторых вспомогательных функций, которые должны быть определены управляемым объектом. Это имеет то преимущество, что уже упомянутый объект (который имеет счетчик ссылок, увеличенный внешним механизмом подсчета ссылок) может быть вставлен в intrusive_ptr - потому что счетчик ссылок больше не является внутренним для интеллектуального указателя, но интеллектуальный указатель использует существующий подсчет ссылок механизм.

unique_ptr - это указатель на передачу права собственности. Вы не можете скопировать его, но вы можете переместить его с помощью конструкторов перемещения C++1x:

unique_ptr<type> p(new type);
unique_ptr<type> q(p); // not legal!
unique_ptr<type> r(move(p)); // legal. p is now empty, but r owns the object
unique_ptr<type> s(function_returning_a_unique_ptr()); // legal!

это семантика, которой подчиняется std::auto_ptr, но из-за отсутствия собственной поддержки для перемещения он не может обеспечить их без подводных камней. unique_ptr автоматически украдет ресурсы из временного другого unique_ptr, который является одной из ключевых особенностей семантики перемещения. auto_ptr будет устаревшим в следующем C++ Стандартный релиз в пользу unique_ptr. C++1x также позволит заполнять объекты, которые являются только подвижными, но не копируемыми в контейнеры. Таким образом, вы можете заполнить unique_ptr в вектор, например. Я остановлюсь здесь и отсылаю вас к прекрасная статья об этом, если вы хотите узнать больше об этом.

scoped_ptr Это самый простой. Когда он выходит за пределы видимости, он разрушается. Следующий код является незаконным (scoped_ptrs не копируются), но проиллюстрирует точку:

std::vector< scoped_ptr<T> > tPtrVec;
{
     scoped_ptr<T> tPtr(new T());
     tPtrVec.push_back(tPtr);
     // raw T* is freed
}
tPtrVec[0]->DoSomething(); // accessing freed memory

shared_ptr ссылка засчитывается. Каждый раз, когда происходит копирование или присвоение, счетчик ссылок увеличивается. Каждый раз, когда деструктор экземпляра запускается, счетчик ссылок для необработанного T * уменьшается. Как только он равен 0, то указатель освобожденный.

std::vector< shared_ptr<T> > tPtrVec;
{
     shared_ptr<T> tPtr(new T());
     // This copy to tPtrVec.push_back and ultimately to the vector storage
     // causes the reference count to go from 1->2
     tPtrVec.push_back(tPtr);
     // num references to T goes from 2->1 on the destruction of tPtr
}
tPtrVec[0]->DoSomething(); // raw T* still exists, so this is safe

weak_ptr является слабой ссылкой на общий указатель, который требует, чтобы вы проверили, есть ли указанная на shared_ptr все еще вокруг

std::vector< weak_ptr<T> > tPtrVec;
{
     shared_ptr<T> tPtr(new T());
     tPtrVec.push_back(tPtr);
     // num references to T goes from 1->0
}
shared_ptr<T> tPtrAccessed =  tPtrVec[0].lock();
if (tPtrAccessed[0].get() == 0)
{
     cout << "Raw T* was freed, can't access it"
}
else
{
     tPtrVec[0]->DoSomething(); // raw 
}

intrusive_ptr обычно используется, когда есть 3rd party smart ptr, который вы должны использовать. Он вызовет свободную функцию для добавления и уменьшения количества ссылок.Смотрите ссылке чтобы увеличить документацию для получения дополнительной информации.

Не забывайте boost::ptr_container в любом обзоре интеллектуальных указателей boost. Они могут быть неоценимы в ситуациях, когда например std::vector<boost::shared_ptr<T> > было бы слишком медленно.

Я поддерживаю совет о просмотре документации. Это не так страшно, как кажется. И несколько коротких подсказок:

  • scoped_ptr - указатель автоматически удаляются, когда он выходит из области видимости. Примечание-нет назначения возможно, но не вводит никаких накладных расходов
  • intrusive_ptr - указатель подсчета ссылок без накладных расходов smart_ptr. Однако сам объект хранит счетчик ссылок
  • weak_ptr - работает вместе с shared_ptr иметь дело с ситуации, приводящие к циклическим зависимостям (прочитайте документацию и найдите в google хорошую картинку;)
  • shared_ptr - общий, самый мощный (и тяжелый) из смарт-указателей (из тех, которые предлагает boost)
  • есть и старые auto_ptr, это гарантирует, что объект, на который он указывает, автоматически уничтожается, когда элемент управления покидает область. Однако он имеет другую семантику копирования, чем остальные ребята.
  • unique_ptr - будет поставляться с C++0x

ответ на редактирование: Да

Comments

    Ничего не найдено.