Как будто вы пытаетесь получить доступ к объекту, который является null
. Рассмотрим ниже пример:
TypeA objA;
. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException
, что имеет смысл.
См. Также этот пример:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
Вот Stroustrup, берут это: Стиль C++ и техника FAQ
В C++, определение
NULL
0, таким образом, существует только эстетическое различие. Я предпочитаю избегать макросов, таким образом, я использую 0. Другая проблема сNULL
состоит в том, что люди иногда по ошибке полагают, что это отличается от 0 и/или не целое число. В предстандартном коде,NULL
иногда определялся к чему-то неподходящему и поэтому/, чтобы избежаться. Это менее распространено в эти дни., Если необходимо назвать нулевого указателя, назовите его
nullptr
; это - то, чем это называют в C++ 11. Затемnullptr
будет ключевое слово.
Однако не потейте маленький материал.
Я всегда использую 0. Не для любой реальной мысли рассуждают, просто потому что, когда я сначала изучал C++, я считал что-то, что рекомендовало использовать 0, и я только что всегда делал его тот путь. В теории могла быть проблема беспорядка в удобочитаемости, но на практике я никогда не сталкивался с такой проблемой в тысячах человеко-часов и миллионах строк кода. Как Stroustrup говорит, это - действительно просто персональная эстетическая проблема, пока стандарт не становится nullptr.
Я предпочитаю использовать ПУСТОЙ УКАЗАТЕЛЬ, поскольку он ясно дает понять, что Ваше намерение является значением, представляет указатель не арифметическое значение. То, что это - макрос, неудачно, но так как это так широко внушило существует мало опасности (если кто-то не делает что-то действительно глупое). Мне действительно жаль, что это не было ключевое слово с начала, но что можно сделать?
Однако у меня нет проблемы с использованием указателей как значения истинности в себе. Так же, как с ПУСТЫМ УКАЗАТЕЛЕМ, это - укоренившаяся идиома.
C++ 09 добавит конструкцию nullptr, которая я думаю, давно ожидается.
Главным образом персональное предпочтение, хотя можно было привести аргумент, что ПУСТОЙ УКАЗАТЕЛЬ делает его довольно очевидным, что объект является указателем, который в настоящее время ни на что не указывает, например,
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 по сравнению с ПУСТЫМ УКАЗАТЕЛЕМ, но это сводится к удобочитаемости также.
Я с Stroustrup на этом:-), Так как ПУСТОЙ УКАЗАТЕЛЬ не является частью языка, я предпочитаю использовать 0.
Я когда-то работал над машиной, где 0 был допустимый адрес, и ПУСТОЙ УКАЗАТЕЛЬ был определен как специальное восьмеричное значение. На той машине (0! = ПУСТОЙ УКАЗАТЕЛЬ), таким образом, код такой как
char *p;
...
if (p) { ... }
не работал бы, как Вы ожидаете. НЕОБХОДИМО было записать
if (p != NULL) { ... }
, Хотя я полагаю, что большинство компиляторов определяет ПУСТОЙ УКАЗАТЕЛЬ как 0 в эти дни, я все еще помню урок от те годы назад: ПУСТОЙ УКАЗАТЕЛЬ не обязательно 0.
Я прекратил использовать ПУСТОЙ УКАЗАТЕЛЬ в пользу 0 давно (а также как большинство других макросов). Я сделал это не только потому, что я хотел избежать макросов как можно больше, но также и потому что ПУСТОЙ УКАЗАТЕЛЬ, кажется, стал злоупотребившим в коде C++ и C. Это, кажется, используется каждый раз, когда 0 значений необходимы, не только для указателей.
На новых проектах, я поместил это в заголовок проекта:
static const int nullptr = 0;
Теперь, то, когда C++ 0x совместимые компиляторы прибывают, все, которое я должен сделать, удаляют ту строку. Хорошее преимущество этого - то, что Visual Studio уже распознает nullptr как ключевое слово и выделяет его соответственно.
Если я вспоминаю правильно ПУСТОЙ, определяется по-другому в заголовках, которые я использовал. Для 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
.
Используйте ПУСТОЙ УКАЗАТЕЛЬ. ПУСТОЙ УКАЗАТЕЛЬ показывает Ваше намерение. То, что это 0, является деталью реализации, которая не должна иметь значения.
Я всегда использую:
NULL
для указателей '\0'
для символов 0.0
для плаваний и удваивается , где 0 сделал бы прекрасный. Это - вопрос сигнального намерения. Однако я не являюсь анальным об этом.
Я думаю, что стандарт гарантирует, что ПУСТОЙ УКАЗАТЕЛЬ == 0, таким образом, можно сделать также. Я предпочитаю ПУСТОЙ УКАЗАТЕЛЬ, потому что он документирует Ваше намерение.
Существует несколько аргументов (один из которых является относительно недавним), которому я верю, противоречат позиции Bjarne по этому.
Используя NULL
допускает поиски на, он - использование, и это также выделяет это, разработчик хотел использовать NULL
указатель, независимо от того, интерпретируется ли это компилятором как NULL
или нет.
пример, который все заключают в кавычки:
void foo(int*);
void foo (int);
void bar() {
foo (NULL); // Calls 'foo(int)'
}
Однако, по крайней мере, по-моему, проблема с вышеупомянутым не состоит в том, что мы используем ПУСТОЙ УКАЗАТЕЛЬ для постоянного нулевого указателя, случается так, что у нас есть перегрузки 'нечто', которые берут совсем другие виды аргументов. Параметр должен быть int
также, поскольку любой другой тип приведет к неоднозначному вызову и тем самым генерирует полезное предупреждение компилятора.
Даже в отсутствие C++ 0x, существуют инструменты, доступные сегодня, которые проверяют, что NULL
используется для указателей, и что 0
используется для целочисленных типов.
std::nullptr_t
тип. Это - новейший аргумент таблице. Проблема 0
и NULL
активно решается для C++ 0x, и можно гарантировать, что для каждой реализации, которая обеспечивает NULL
, самая первая вещь, которую они сделают:
#define NULL nullptr
Для тех, кто использует NULL
, а не 0
, изменение будет улучшением безопасности типов с минимальным усилием - если что-либо, это может также поймать несколько ошибок, где они использовали NULL
для [1 115]. Для кого-либо использующего 0
сегодня.... erm... хорошо, надо надеяться, у них есть хорошее знание регулярных выражений...
Я обычно использую 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" для большего количества информации.
Я стараюсь избегать целого вопроса при помощи ссылок C++, если это возможно. Вместо
void foo(const Bar* pBar) { ... }
Вы могли бы часто мочь записать
void foo(const Bar& bar) { ... }
Конечно, это не всегда работает; но нулевые указатели могут злоупотребиться.
Кто-то однажды сказал мне ... Я собираюсь переопределить 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).
Странно, никто, включая Страуструп, не упомянул об этом. Много говоря о стандартах и эстетике, никто не заметил, что опасно использовать 0
вместо NULL
, например, в списке переменных аргументов в архитектура, где sizeof (int)! = sizeof (void *)
. Как и Страуструп, я предпочитаю 0
из эстетических соображений, но нужно быть осторожным, чтобы не использовать его там, где его тип может быть неоднозначным.