интеллектуальные указатели (повышение) объяснены

Как ответил Здан, printf не пишет напрямую в консоль, а записывает в стандартный поток вывода с помощью WriteFile Windows API, который, в свою очередь, вызывает [112 ] системный вызов. Затем выходные данные выбираются хостом консоли conhost.exe и отображаются на консоли Windows.

218
задан Null 1 April 2016 в 07:18
поделиться

4 ответа

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

легко, когда у Вас есть свойства, что можно присвоить каждый интеллектуальный указатель. Существует три важных свойства.

  • никакое владение во всем
  • передача права собственности
  • доля владения

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

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

Некоторые интеллектуальные указатели владения не поддерживают ни второго, ни третьего. Они не могут поэтому быть возвращены из функций или переданы где-то в другом месте. Который наиболее подходит для 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 укажет на объект, уже удаленный, то он заметит Вас путем выдачи исключения. Используя weak_ptr является самым выгодным, когда у Вас есть циклическая ссылка: Подсчет ссылок не может легко справиться с такой ситуацией.

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

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

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!

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

336
ответ дан Johannes Schaub - litb 23 November 2019 в 04:11
поделиться

scoped_ptr является самым простым. Когда это выходит из объема, это уничтожается. Следующий код недопустим (scoped_ptrs, non-copyable), но проиллюстрирует тезис:

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 обычно, когда существует третья сторона умный ptr, необходимо использовать. Это вызовет бесплатную функцию, чтобы добавить и постепенно уменьшить подсчет ссылок. Посмотрите ссылка для повышения документации для большего количества информации

91
ответ дан Maarten Bodewes 23 November 2019 в 04:11
поделиться

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

20
ответ дан timday 23 November 2019 в 04:11
поделиться

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

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

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

12
ответ дан Anonymous 23 November 2019 в 04:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: