Я где-то читал, что при использовании C ++ рекомендуется не использовать указатели. Почему указатели такие плохие идеи, когда вы используете C ++. Для программистов C, которые привыкли использовать указатели, что является лучшей альтернативой и подходом в C ++?
45
NetConnection
отключением экземпляров от сервера ( stackoverflow.com/questions/14780456/… ), а также проблема с наличием в программе нескольких объектов, которые она специально откажется собирать. ...GCRoots are never garbage collected.
и начатый абзацThe MMgc is considered a conservative collector for mark/sweep.
). Технически это проблема в Adobe Virtual Machine 2, а не в самой AS3, но когда у вас возникают подобные проблемы на языках более высокого уровня, в которые встроена сборка мусора, у вас часто нет никакого истинного способа отладки языка. эти проблемы полностью выходят за рамки программы. ...Ответы:
Я думаю, что они означают, что вы должны использовать умные указатели вместо обычных указателей.
В C ++ акцент будет делаться на сборку мусора и предотвращение утечек памяти (просто назвать два). Указатели являются фундаментальной частью языка, поэтому их использование практически невозможно, кроме как в большинстве программ.
источник
Поскольку я - тот, кто опубликовал полемику «не используйте чертовы указатели», я чувствую, что должен прокомментировать здесь.
Прежде всего, как полемика, это, очевидно, крайняя точка зрения. Там является , безусловно , законным использованием (сырья) указателей. Но я (и многие профессиональные программисты на С ++) утверждаю, что эти случаи чрезвычайно редки. Но на самом деле мы имеем в виду следующее:
Первый:
Здесь «собственная память», по сути, означает, что в какой-то момент
delete
вызывается этот указатель (но он более общий, чем этот). Это утверждение можно смело считать абсолютным. Только исключение при реализации собственного интеллектуального указателя (или стратегии управления другой памяти). И даже там , вы должны нормально все еще использовать смарт - указатель на низком уровне.Обоснование этого довольно простое: необработанные указатели, собственная память которых вводит источник ошибки. И эти ошибки распространены в существующем программном обеспечении: утечки памяти и двойное удаление - оба являются прямым следствием неясного владения ресурсами (но в противоположном направлении).
Эта проблема может быть полностью устранена, практически бесплатно, просто используя умные указатели вместо необработанных указателей (предостережение: это, конечно, требует размышлений; общие указатели могут привести к циклам и, таким образом, к утечкам памяти - но это легко избежать).
Во-вторых:
В отличие от других языков, C ++ имеет очень сильную поддержку семантики значений и просто не нуждается в косвенных указателях. Это не было немедленно понято - исторически, C ++ был изобретен, чтобы облегчить легкую ориентацию объекта в C, и в значительной степени полагался на построение графов объектов, которые были связаны указателями. Но в современном C ++ эта парадигма редко является лучшим выбором, и современные идиомы C ++ часто вообще не нуждаются в указателях . Они оперируют ценностями, а не указателями.
К сожалению, это сообщение до сих пор не завоевало популярность в сообществе пользователей C ++. В результате большая часть написанного кода на C ++ все еще усеяна лишними указателями, которые делают код сложным, медленным и неисправным / ненадежным.
Для тех, кто знает современный C ++, ясно, что вам очень редко нужны какие-либо указатели (умные или необработанные; кроме случаев использования их в качестве итераторов). Получающийся код короче, менее сложен, более читабелен, часто более эффективен и более надежен.
источник
std::unique_ptr
. Кроме того, почему нетptr_vec
? Но обычно вектор значений с по-прежнему будет меняться быстрее (особенно с семантикой перемещения).boost::variant
с,recursive_wrapper
вероятно, мое любимое решение для представления DAG.Просто потому, что вам доступны абстракции, которые скрывают более темпераментные аспекты использования указателей, такие как доступ к необработанной памяти и очистка после ваших выделений. Благодаря умным указателям, классам контейнеров и шаблонам проектирования, таким как RAII, необходимость в использовании необработанных указателей уменьшается. Тем не менее, как и любая абстракция, вы должны понять, как они на самом деле работают, прежде чем выйти за их пределы.
источник
Относительно просто менталитет Си - «Есть проблема? Использовать указатель». Это можно увидеть в строках C, указателях функций, указателях-итераторах, указателях-указателях, пустых указателях - даже в первые дни C ++ с указателями на члены.
Но в C ++ вы можете использовать значения для многих или всех этих задач. Нужна функция абстракция?
std::function
, Это значение, которое является функцией.std::string
? Это значение, это строка. Вы можете увидеть похожие подходы во всем C ++. Это значительно упрощает анализ кода как для людей, так и для компиляторов.источник
Одна из причин - слишком широкое применение указателей. Их можно использовать для итерации по контейнерам, чтобы избежать копирования больших объектов при передаче в функцию, нетривиального управления продолжительностью жизни, доступа к произвольным местам в памяти и т. Д. И как только вы используете их для одной цели, становятся доступны другие их функции немедленно независимо от намерения.
Выбор инструмента для конкретной цели делает код более простым и более наглядным - итераторы для итераций, интеллектуальные указатели для управления временем жизни и т. Д.
источник
Помимо перечисленных причин, есть и очевидная причина: лучшая оптимизация. Анализ алиасов слишком сложен из-за арифметики указателей, тогда как ссылки намекают на оптимизатор, поэтому более глубокий анализ алиасов возможен, если используются только ссылки.
источник
Помимо риска утечек памяти, указанных в @jmquigley, указатель и арифметика указателя могут считаться проблематичными, поскольку указатели могут указывать повсюду в памяти, вызывая «трудности с обнаружением ошибок» и «уязвимости безопасности».
Вот почему они были почти заброшены в C # и Java.
источник
unsafe
ключевое словоC ++ поддерживает большинство функций C , а также объекты и классы. С уже были указатели и прочее.
Указатели являются очень полезной техникой, которую можно комбинировать с объектной ориентацией, и C ++ поддерживает их. Но этот метод сложен в обучении и труден для понимания, и его очень легко вызвать нежелательные ошибки.
Многие новые языки программирования делают вид, что не используют указатели на объекты, такие как Java, .NET, Delphi, Vala, PHP, Scala. Но указатели по-прежнему используются «за кадром». Эти методы «скрытого указателя» называются «ссылками».
В любом случае, я рассматриваю указатель (и) как шаблон программирования, как правильный способ решения определенных проблем, как это делает объектно-ориентированное программирование .
Другие разработчики могут иметь другое мнение. Но я предлагаю студентам и программистам научиться:
(1) Используйте указатели без объектов
(2) объекты без указателей
(3) явные указатели на объекты
(4) «скрытые» указатели на объекты ( ссылка AKA ) ;-)
В этой последовательности.
Даже если это трудно учить, и трудно учиться. Объект Pascal (Delphi, FreePascal, другие) и
C++
(не Java или C #) могут быть использованы для этих целей.И позже начинающие программисты могут переходить на языки программирования «скрытые указатели на объекты», такие как: Java, C #, объектно-ориентированный PHP и другие.
источник
Говоря о VC6, когда вы приводите указатель класса (который вы создаете) в переменную (например, DWORD), даже если этот указатель является локальным, вы можете получить доступ к классу через все функции, которые используют одну и ту же кучу. Созданный экземпляр класса определяется как локальный, но на самом деле это не так. Насколько я знаю, любой адрес переменной кучи, структуры или класса уникален на протяжении всей жизни класса хостинга.
Пример:
РЕДАКТИРОВАТЬ Это очень маленькая часть исходного кода. Класс CSRecodset является только классом приведения в CXdbRecordset, где весь реальный код. Поступая так, я могу позволить пользователю воспользоваться тем, что я написал, не теряя своих прав. Я не претендую на то, чтобы продемонстрировать, что мой движок баз данных работает профессионально, но он действительно работает.
РЕДАКТИРОВАТЬ: запрошено DeadMG:
источник
DWORD
является оскорбительным и, возможно, неправильным (DWORD не обязательно достаточно широк, чтобы содержать указатель). Если вам нужен нетипизированный указатель, используйтеvoid*
- но когда вам это нужно в C ++, у вас часто возникает проблема с дизайном в вашем коде, которую вы должны исправить.