Указатели плохие? - PullRequest
       5

Указатели плохие?

14 голосов
/ 02 ноября 2010

Я сейчас программирую на C ++ и люблю использовать указатели. Но, похоже, что другие, более новые языки, такие как Java, C # и Python, не позволяют вам явно объявлять указатели. Другими словами, вы не можете писать и int x, и int * y, и иметь x значение, в то время как y - указатель на любом из этих языков. В чем причина этого?

Ответы [ 6 ]

17 голосов
/ 02 ноября 2010

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

На вашем примере, почему вы хотите, чтобы и x, и y указывали на одну и ту же память?Почему бы просто не назвать это x?

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

12 голосов
/ 02 ноября 2010

Я начну с одной из моих любимых цитат Скотта Мейерса :

Когда я говорю о работе с исключениями, я учу людей двум вещам:

  • Указатели являются вашими врагами, потому что они приводят к проблемам, которые auto_ptr предназначен для устранения.

  • Указатели являются вашими друзьями, потому что операции с указателямине могу бросить.

Тогда я говорю им, чтобы у них был хороший день: -)


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

Однако в хорошо написанном коде приложения C ++ вам никогда не придется работать с необработанными указателями.Никогда.Вы должны всегда использовать какой-то уровень абстракции вместо прямой работы с указателями:

  • Используйте ссылки вместо указателей везде, где это возможно.Ссылки не могут быть пустыми, и они облегчают понимание кода, его написание и проверку кода.

  • Используйте интеллектуальные указатели для управления любыми указателями, которые вы используете.Интеллектуальные указатели, такие как shared_ptr, auto_ptr и unique_ptr, помогают гарантировать, что вы не потеряете ресурсы или освободите ресурсы преждевременно.

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

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

  • Когда вы работаетес устаревшими или сторонними API, и вы обязательно должны использовать необработанные указатели, напишите класс для инкапсуляции использования этого API.

C ++ имеет автоматическое управление ресурсами в форме Scope-Bound ResourceУправление (SBRM, также называемое Ресурсом Приобретение - Инициализация, или RAII).Используй это.Если вы не используете его, вы делаете это неправильно.

6 голосов
/ 02 ноября 2010

Указателями можно злоупотреблять, а управляемые языки предпочитают защищать вас от потенциальных ловушек.Однако указатели, безусловно, неплохие - они являются неотъемлемой особенностью языков C и C ++, и написание кода C / C ++ без них является сложным и громоздким.

3 голосов
/ 02 ноября 2010

Я пытаюсь ответить на вопрос ОП напрямую:

Другими словами, вы не можете написать оба int x и int * y, а x будет значение в то время как у указатель, в любом из эти языки. В чем причина за этим?

Причиной этого является модель управляемой памяти на этих языках. В C # (или Python, или Java, ...) время жизни ресурсов и, следовательно, использование памяти управляется автоматически базовой средой выполнения или, если быть точным, сборщиком мусора Вкратце: приложение не контролирует расположение ресурса в памяти. Он не указан - и даже не гарантируется, что он останется постоянным в течение всего срока службы ресурса. Следовательно, понятие указателя как «местоположения чего-либо в виртуальной или физической памяти» совершенно не имеет значения.

3 голосов
/ 02 ноября 2010

Истинный «указатель» имеет две характеристики.

  • Он содержит адрес другого объекта (или примитива)
    • и предоставляет числовую природу этого адреса, чтобы вы могли сделатьарифметика.

Обычно арифметическими операциями, определенными для указателей, являются:

  1. Добавление целого числа к указателю в массиве, который возвращает адресдругой элемент.
  2. Вычитание двух указателей в один и тот же массив, который возвращает число промежуточных элементов (включая один конец).
  3. Сравнение двух указателей в одном массиве, который указывает, какиеЭлемент находится ближе к началу массива.

Управляемые языки обычно ведут вас по пути «ссылок» вместо указателей.Ссылка также содержит адрес другого объекта (или примитива), но арифметика запрещена.

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

Вместе это обеспечивает безопасность типов, но с ужасной потерей универсальности.

0 голосов
/ 29 января 2013

Как кто-то уже упоминал, указатели могут, и фактически, будут работать неправильно, если у вас большое приложение.Это одна из причин, по которой мы иногда видим проблемы с Windows из-за созданных указателей NULL!Лично мне не нравятся указатели, потому что они вызывают ужасную утечку памяти, и независимо от того, насколько хорошо вы управляете своей памятью, она в конечном итоге выследит вас в некоторых отношениях.Я испытал это с OpenCV, когда работал с приложениями для обработки изображений.Наличие множества указателей, плавающих вокруг, помещая их в список и затем получая их позже, вызвало у меня проблемы.Но опять же, есть хорошие стороны использования указателей, и часто это хороший способ настроить ваш код.Все зависит от того, что вы делаете, с какими спецификациями вы должны отвечать и т. Д.

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