Указатели, интеллектуальные указатели или совместно использованные указатели? [дубликат]

HttpRequest имеет свойство Query, которое предоставляет анализируемую строку запроса через интерфейс IReadableStringCollection :

/// 
/// Gets the query value collection parsed from owin.RequestQueryString.
/// 
/// The query value collection parsed from owin.RequestQueryString.
public abstract IReadableStringCollection Query { get; }

Это обсуждение на GitHub указывает на это также.

115
задан Mateen Ulhaq 3 December 2011 в 02:58
поделиться

5 ответов

Sydius обрисовал в общих чертах типы довольно хорошо:

  • Нормальные указатели просто, что - они указывают на некоторую вещь в памяти где-нибудь. Кто владеет им? Только комментарии сообщат. Кто освобождает его? Надо надеяться, владелец в какой-то момент.
  • Интеллектуальные указатели являются общим термином, которые покрывают много типов; я предположу, что Вы имели в виду ограниченный по объему указатель, который использует шаблон RAII . Это - выделенный стеку объект, который обертывает указатель; когда это выходит из объема, это звонит, удаляют на указателе, который это обертывает. Это "владеет" содержавшим указателем, в котором это отвечает за deleteing он в какой-то момент. Они позволяют Вам получать необработанную ссылку на указатель, который они обертывают для передачи другим методам, а также выпуск указатель, позволяя кому-то еще владеть ею. Копирование их не имеет смысла.
  • Общие указатели являются выделенным стеку объектом, который обертывает указатель так, чтобы Вы не знали, кто владеет им. Когда последний общий указатель для объекта в памяти будет разрушен, обернутый указатель будет также удален.

Как насчет того, когда необходимо использовать их? Вы или сделаете интенсивное использование ограниченных по объему указателей или совместно использованных указателей. Сколько потоков работает в Вашем приложении? Если ответ "потенциально много", совместно использованные указатели могут оказаться узким местом производительности, если используется везде. Причиной, являющейся, который создавать/копировать/разрушать общий указатель, должна быть атомарная операция, и это может препятствовать производительности, если у Вас есть много выполнений потоков. Однако это будет не всегда иметь место - только тестирование скажет Вам наверняка.

существует аргумент (что мне нравится) против общих указателей - при помощи их, Вы позволяете программистам игнорировать, кто владеет указателем. Это может привести к щекотливым ситуациям с циклическими ссылками (Java обнаружит их, но совместно использованные указатели не могут), или общая лень программиста в большой кодовой базе.

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

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

144
ответ дан hazzen 24 November 2019 в 02:26
поделиться

термин "интеллектуальный указатель" включает общие указатели, автоматические указатели, блокируя указатели и других. Вы означали говорить автоматический указатель (более двусмысленно известный как "владение указателем"), не интеллектуальный указатель.

Немые указатели (T*) никогда не являются лучшим решением. Они заставляют Вас сделать явное управление памятью, которое является подробным, подверженным ошибкам, и иногда почти невозможным. Но что еще более важно, они не сигнализируют о Вашем намерении.

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

Общие указатели удаляют пуант, когда последний общий указатель на него уничтожается. Это полезно, когда Вы хотите легкую задачу, открытая схема устройства хранения данных, где ожидаемое время жизни и владение могут значительно различаться в зависимости от ситуации. Из-за потребности сохранить (атомарный) счетчик, они немного медленнее, чем автоматические указатели. Некоторые говорят половину в шутку, что совместно использованные указатели для людей, которые не могут разработать системы - судят для себя.

Для существенного дубликата к общим указателям, ищите слабые указатели также.

33
ответ дан 24 November 2019 в 02:26
поделиться

Интеллектуальные указатели вымоются после того, как они выйдут из объема (таким образом, удаляющий страх перед большинством утечек памяти). Общие указатели являются интеллектуальными указателями, которые проводят подсчет того, сколько экземпляров указателя существует, и только очищает память, когда количество достигает нуля. В целом только используйте совместно использованные указатели (но обязательно используйте корректный вид - существует различный для массивов). Они имеют непосредственное отношение RAII.

21
ответ дан Sydius 24 November 2019 в 02:26
поделиться

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

  • считаемый Reference (например, повышение:: shared_ptr / станд.:: tr1:shared_ptr)
  • не считаемая ссылка (например, повышение:: scoped_ptr / станд.:: auto_ptr)

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

(я предлагаю избежать auto_ptr, он имеет некоторые серьезные дефекты, если используется неправильно)

8
ответ дан d0k 24 November 2019 в 02:26
поделиться

Для добавления маленького бита к ответу Sydius интеллектуальные указатели будут часто предоставлять более стабильное решение путем ловли многих легких совершать ошибки. Необработанные указатели будут иметь некоторые преимущества производительности и могут быть более гибкими при определенных обстоятельствах. Вы можете также быть вынуждены использовать необработанные указатели при соединении в определенные сторонние библиотеки.

5
ответ дан SmacL 24 November 2019 в 02:26
поделиться
Другие вопросы по тегам:

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