Почему библиотеки и фреймворки C ++ никогда не используют умные указатели?
==========================================================================

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

Однако я заметил, что фреймворки, такие как Qt, wxWidgets и библиотеки, такие как Boost, никогда не возвращают и не ожидают интеллектуальных указателей, как если бы они вообще не использовали их. Вместо этого они возвращаются или ожидают сырых указателей. Есть ли причина для этого? Должен ли я держаться подальше от умных указателей при написании общедоступного API и почему?

Просто интересно, почему умные указатели рекомендуются, когда многие крупные проекты их избегают.

 что многие библиотеки были написаны до появления стандартных интеллектуальных указателей, главной причиной, вероятно, является отсутствие стандартного двоичного интерфейса приложений C ++ (ABI).

Если вы пишете библиотеку только для заголовков, вы можете передать интеллектуальные указатели и стандартные контейнеры своему сердечному контенту. Их источник доступен вашей библиотеке во время компиляции, поэтому вы полагаетесь только на стабильность их интерфейсов, а не на их реализации.

Но из-за отсутствия стандартного ABI вы вообщеcannot передать эти объекты безопасно через границы модуля. GCC`shared_ptr` вероятно, отличается от MSVC`shared_ptr`, который тоже может отличаться от Intel`shared_ptr`, Даже сsame компилятор, эти классы не гарантированно двоично совместимы между версиями.

Суть в том, что если вы хотите распространятьprebuilt версия вашей библиотеки, вам нужен стандартный ABI, на который можно положиться. У C его нет, но поставщики компиляторов очень хорошо разбираются во взаимодействии между библиотеками C для данной платформы - существуют стандарты де-факто.

Ситуация не так хороша для C ++. Отдельные компиляторы могут обрабатывать взаимодействие между своими собственными двоичными файлами, поэтому у вас есть возможность распространять версию для каждого поддерживаемого компилятора, часто GCC и MSVC. Но в свете этого большинство библиотек просто экспортируют интерфейс C, а это означает, что указатели не используются.

Небиблиотечный код должен, однако, обычно предпочитать умные указатели необработанным.



 в какой области вы работаете. Я пишу игровые движки для жизни, мы избегаем ускорения, как чумы, в играх накладные расходы ускорения неприемлемы. В нашем основном движке мы закончили тем, что написали собственную версию stl (очень похожую на ea stl).

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



 пытаясь стать Java. Я считаю, что сейчас у него действительно есть свои умные указатели, но в целом это едва ли не вершина дизайна. Насколько я знаю, wxWidgets был разработан задолго до того, как были написаны полезные умные указатели.

Что касается Boost, я полностью ожидаю, что они используют умные указатели, где это уместно. Возможно, вам придется быть более конкретным.

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



Smart pointers became part of standard just recently. Till then they
were part of other libraries
Their primary use is to avoid memory leaks; many libraries
don't have their own memory management; Generally they provide
utilities and APIs
They are implemented as wrapper, since they are actually objects and not pointers. Which has additional time/space cost, compared to raw pointers; The users of the libraries may not want to have such overheads

**Edit**Использование интеллектуальных указателей полностью зависит от разработчика. Это зависит от различных факторов.

In performance critical systems, you may not want to use smart
pointers which generates overhead

The project which needs the backward compatibility, you may not want
to use the smart pointers which has C++11 specific features

**Edit2** Из-за нижнего прохода в течение 24 часов есть ряд отрицательных голосов. Я не понимаю, почему за этот ответ проголосовали, хотя ниже приведено лишь дополнительное предложение, а не ответ.  

Тем не менее, C ++ всегда облегчает вам открывать опции. :) например

И в вашем коде используйте его как:

Для тех, кто говорит, что умный указатель и необработанный указатель разные, я согласен с этим. Код выше был простоidea где можно написать код, который является взаимозаменяемым только с`#define`, это неcompulsion;

Например,`T*` должен быть удален явно, а умный указатель - нет. Мы можем иметь шаблон`Destroy()` справиться с этим.

и использовать его как:

Таким же образом, для необработанного указателя мы можем скопировать его напрямую, а для умного указателя мы можем использовать специальную операцию.

куда`Assign()` как есть:



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

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

Интеграция с C - еще одна проблема.

Другая проблема заключается в том, что умные указатели являются частью STL. C ++ предназначен для использования без STL.



non-standards, so each library tend to reinvent its own (NIH syndrom & dependencies issues)
potential cost

default умный указатель, в том, что это бесплатно, является`unique_ptr`, К сожалению, это требует семантики перемещения C ++ 11, которая появилась только недавно. Все остальные умные указатели имеют стоимость (`shared_ptr`, `intrusive_ptr`) или имеют менее чем идеальную семантику (`auto_ptr`).

С C ++ 11 за углом, принося`std::unique_ptr`Можно было бы подумать, что это наконец закончилось ... Я не так оптимистичен.

Лишь несколько крупных компиляторов реализуют большую часть C ++ 11 и только в своих последних версиях. Мы можем ожидать, что основные библиотеки, такие как QT и Boost, будут некоторое время сохранять совместимость с C ++ 03, что несколько препятствует широкому внедрению новых и блестящих интеллектуальных указателей.



 они имеют свое применение, особенно в приложениях, где вы должны передавать объект вокруг.

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

Я мог бы взять в качестве примера библиотеку, над которой мы работали, где после нескольких месяцев разработки я понял, что мы использовали указатели и умные указатели только в нескольких классах (3-5% всех классов).

Переходя**variables by reference** в большинстве мест было достаточно, мы использовали умные указатели всякий раз, когда у нас был объект, который мог быть нулевым, и необработанные указатели, когда нас заставляла библиотека, которую мы использовали.

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



 на которые вы ссылаетесь, но время от времени я читал подобные вещи. Я подозреваю, что авторы таких статей склонны склоняться к предвзятому отношению к программированию в стиле C ++. Если писатель программирует на C ++ только тогда, когда он должен, а затем возвращается в Java или тому подобное, как только может, тогда он действительно не разделяет мышление C ++.

Можно предположить, что некоторые или большинство авторов пишут о менеджерах памяти для сбора мусора. Я не знаю, но думаю иначе, чем они.

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

Одна из замечательных особенностей C ++ - поддержка программирования на встроенных системах. Использование голых указателей является частью этого.

Update:  Комментатор правильно заметил, что C ++ новый`unique_ptr` (доступно с TR1) не учитывает ссылки. Комментатор также имеет другое определение «умный указатель»; чем я имею в виду. Он может быть прав насчет определения.

Further update:  Приведенная ниже цепочка комментариев освещает. Все это рекомендуется к прочтению.