Вы используете ПУСТОЙ УКАЗАТЕЛЬ или 0 (нуль) для указателей в C++?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

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

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
185
задан Yu Hao 22 June 2014 в 14:47
поделиться

16 ответов

Вот Stroustrup, берут это: Стиль C++ и техника FAQ

В C++, определение NULL 0, таким образом, существует только эстетическое различие. Я предпочитаю избегать макросов, таким образом, я использую 0. Другая проблема с NULL состоит в том, что люди иногда по ошибке полагают, что это отличается от 0 и/или не целое число. В предстандартном коде, NULL иногда определялся к чему-то неподходящему и поэтому/, чтобы избежаться. Это менее распространено в эти дни.

, Если необходимо назвать нулевого указателя, назовите его nullptr; это - то, чем это называют в C++ 11. Затем nullptr будет ключевое слово.

Однако не потейте маленький материал.

179
ответ дан ThiefMaster 23 November 2019 в 05:52
поделиться

Я всегда использую 0. Не для любой реальной мысли рассуждают, просто потому что, когда я сначала изучал C++, я считал что-то, что рекомендовало использовать 0, и я только что всегда делал его тот путь. В теории могла быть проблема беспорядка в удобочитаемости, но на практике я никогда не сталкивался с такой проблемой в тысячах человеко-часов и миллионах строк кода. Как Stroustrup говорит, это - действительно просто персональная эстетическая проблема, пока стандарт не становится nullptr.

1
ответ дан Gerald 23 November 2019 в 05:52
поделиться

Я предпочитаю использовать ПУСТОЙ УКАЗАТЕЛЬ, поскольку он ясно дает понять, что Ваше намерение является значением, представляет указатель не арифметическое значение. То, что это - макрос, неудачно, но так как это так широко внушило существует мало опасности (если кто-то не делает что-то действительно глупое). Мне действительно жаль, что это не было ключевое слово с начала, но что можно сделать?

Однако у меня нет проблемы с использованием указателей как значения истинности в себе. Так же, как с ПУСТЫМ УКАЗАТЕЛЕМ, это - укоренившаяся идиома.

C++ 09 добавит конструкцию nullptr, которая я думаю, давно ожидается.

3
ответ дан Michael Burr 23 November 2019 в 05:52
поделиться

Главным образом персональное предпочтение, хотя можно было привести аргумент, что ПУСТОЙ УКАЗАТЕЛЬ делает его довольно очевидным, что объект является указателем, который в настоящее время ни на что не указывает, например,

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

IIRC, стандарт, не требует, чтобы ПУСТОЙ УКАЗАТЕЛЬ был 0, так использование вообще определяется в < stddef.h> является, вероятно, лучшим для Вашего компилятора.

Другой фасет к аргументу - необходимо ли использовать логические сравнения (неявный бросок к bool) или проверка explicity по сравнению с ПУСТЫМ УКАЗАТЕЛЕМ, но это сводится к удобочитаемости также.

3
ответ дан Jimmy 23 November 2019 в 05:52
поделиться

Я с Stroustrup на этом:-), Так как ПУСТОЙ УКАЗАТЕЛЬ не является частью языка, я предпочитаю использовать 0.

3
ответ дан Rob 23 November 2019 в 05:52
поделиться

Я когда-то работал над машиной, где 0 был допустимый адрес, и ПУСТОЙ УКАЗАТЕЛЬ был определен как специальное восьмеричное значение. На той машине (0! = ПУСТОЙ УКАЗАТЕЛЬ), таким образом, код такой как

char *p;

...

if (p) { ... }

не работал бы, как Вы ожидаете. НЕОБХОДИМО было записать

if (p != NULL) { ... }

, Хотя я полагаю, что большинство компиляторов определяет ПУСТОЙ УКАЗАТЕЛЬ как 0 в эти дни, я все еще помню урок от те годы назад: ПУСТОЙ УКАЗАТЕЛЬ не обязательно 0.

11
ответ дан Jared Burrows 23 November 2019 в 05:52
поделиться

Я прекратил использовать ПУСТОЙ УКАЗАТЕЛЬ в пользу 0 давно (а также как большинство других макросов). Я сделал это не только потому, что я хотел избежать макросов как можно больше, но также и потому что ПУСТОЙ УКАЗАТЕЛЬ, кажется, стал злоупотребившим в коде C++ и C. Это, кажется, используется каждый раз, когда 0 значений необходимы, не только для указателей.

На новых проектах, я поместил это в заголовок проекта:

static const int nullptr = 0;

Теперь, то, когда C++ 0x совместимые компиляторы прибывают, все, которое я должен сделать, удаляют ту строку. Хорошее преимущество этого - то, что Visual Studio уже распознает nullptr как ключевое слово и выделяет его соответственно.

35
ответ дан Ferruccio 23 November 2019 в 05:52
поделиться

Если я вспоминаю правильно ПУСТОЙ, определяется по-другому в заголовках, которые я использовал. Для C это определяется как (пусто*) 0, и для C++ это, определяет как всего 0. Код смотрел что-то как:

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

Лично я все еще использую Нулевое значение для представления нулевых указателей, оно делает его явным, что Вы используете указатель, а не некоторый целочисленный тип. Да внутренне Нулевое значение все еще 0, но оно не представлено как таковое.

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

, Например, предпочтите использовать:

if (pointer_value != NULL || integer_value == 0)

, а не:

if (pointer_value || !integer_value)
<час>

Достаточны, чтобы сказать, что это все исправлено в C++ 11, где можно просто использовать nullptr вместо NULL, и также nullptr_t, который является типом nullptr.

16
ответ дан Daemin 23 November 2019 в 05:52
поделиться

Используйте ПУСТОЙ УКАЗАТЕЛЬ. ПУСТОЙ УКАЗАТЕЛЬ показывает Ваше намерение. То, что это 0, является деталью реализации, которая не должна иметь значения.

45
ответ дан Andy Lester 23 November 2019 в 05:52
поделиться

Я всегда использую:

  • NULL для указателей
  • '\0' для символов
  • 0.0 для плаваний и удваивается

, где 0 сделал бы прекрасный. Это - вопрос сигнального намерения. Однако я не являюсь анальным об этом.

36
ответ дан Donald Duck 23 November 2019 в 05:52
поделиться

Я думаю, что стандарт гарантирует, что ПУСТОЙ УКАЗАТЕЛЬ == 0, таким образом, можно сделать также. Я предпочитаю ПУСТОЙ УКАЗАТЕЛЬ, потому что он документирует Ваше намерение.

9
ответ дан Mark Ransom 23 November 2019 в 05:52
поделиться

Существует несколько аргументов (один из которых является относительно недавним), которому я верю, противоречат позиции Bjarne по этому.

  1. Документация намерения

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

  1. Перегрузка указателя и 'интервала' относительно редка

пример, который все заключают в кавычки:

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

Однако, по крайней мере, по-моему, проблема с вышеупомянутым не состоит в том, что мы используем ПУСТОЙ УКАЗАТЕЛЬ для постоянного нулевого указателя, случается так, что у нас есть перегрузки 'нечто', которые берут совсем другие виды аргументов. Параметр должен быть int также, поскольку любой другой тип приведет к неоднозначному вызову и тем самым генерирует полезное предупреждение компилятора.

  1. инструменты Analysis могут помочь СЕГОДНЯ!

Даже в отсутствие C++ 0x, существуют инструменты, доступные сегодня, которые проверяют, что NULL используется для указателей, и что 0 используется для целочисленных типов.

  1. C++ 11 будет иметь новое std::nullptr_t тип.

Это - новейший аргумент таблице. Проблема 0 и NULL активно решается для C++ 0x, и можно гарантировать, что для каждой реализации, которая обеспечивает NULL, самая первая вещь, которую они сделают:

#define NULL  nullptr

Для тех, кто использует NULL, а не 0, изменение будет улучшением безопасности типов с минимальным усилием - если что-либо, это может также поймать несколько ошибок, где они использовали NULL для [1 115]. Для кого-либо использующего 0 сегодня.... erm... хорошо, надо надеяться, у них есть хорошее знание регулярных выражений...

122
ответ дан Chnossos 23 November 2019 в 05:52
поделиться

Я обычно использую 0. Мне не нравятся макросы, и нет никакой гарантии, что некоторый сторонний заголовок, который Вы используете, не переопределяет ПУСТОЙ УКАЗАТЕЛЬ, чтобы быть чем-то нечетным.

Вы могли использовать объект nullptr, как предложено Scott Meyers и другими, пока C++ не получает nullptr ключевое слово:

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

Google "nullptr" для большего количества информации.

11
ответ дан jon-hanson 23 November 2019 в 05:52
поделиться

Я стараюсь избегать целого вопроса при помощи ссылок C++, если это возможно. Вместо

void foo(const Bar* pBar) { ... }

Вы могли бы часто мочь записать

void foo(const Bar& bar) { ... }

Конечно, это не всегда работает; но нулевые указатели могут злоупотребиться.

4
ответ дан Ðаn 23 November 2019 в 05:52
поделиться

Кто-то однажды сказал мне ... Я собираюсь переопределить NULL на 69. С тех пор я не использую его: P

Это делает ваш код довольно уязвимым.

Править :

Не все в стандарте идеально. Макрос NULL является константой нулевого указателя C ++, определяемой реализацией, не полностью совместимой с макросом C NULL, который, помимо скрытого неявного типа, преобразует его в бесполезный и подверженный ошибкам инструмент.

NULL ведет себя не как нулевой указатель, а как литерал O / OL.

Скажите, что следующий пример не сбивает с толку:

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

Из-за всего этого в новом стандарте появляется std :: nullptr_t

Если вы не хотите ждать выхода нового стандарта и хотите использовать nullptr , используйте хотя бы достойный вариант, например, предложенный Мейерсом (см. комментарий jon.h).

1
ответ дан 23 November 2019 в 05:52
поделиться

Странно, никто, включая Страуструп, не упомянул об этом. Много говоря о стандартах и ​​эстетике, никто не заметил, что опасно использовать 0 вместо NULL , например, в списке переменных аргументов в архитектура, где sizeof (int)! = sizeof (void *) . Как и Страуструп, я предпочитаю 0 из эстетических соображений, но нужно быть осторожным, чтобы не использовать его там, где его тип может быть неоднозначным.

5
ответ дан 23 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

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