Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Для обеспечения немного большего количества боеприпасов 'избегают std::auto_ptr
' лагерь: auto_ptr
удерживается от использования в следующем стандарте (C++ 0x). Я думаю, что это одно является достаточно хорошими боеприпасами для любого аргумента для использования чего-то еще.
Однако как [1 110] Konrad Rudolph упомянутый, замена по умолчанию для auto_ptr
должна, вероятно, быть boost::scoped_ptr
. Семантика scoped_ptr
более тесно те соответствия auto_ptr
и это предназначается для подобного использования. Следующий C++ 09 стандартов будут иметь что-то подобным, назвал unique_ptr.
Однако использование shared_ptr
где угодно, что scoped_ptr
должен использоваться, ничего не повредит, оно просто добавит очень небольшой бит неэффективности для контакта с подсчетом ссылок, если объект на самом деле никогда не будет быть общим. Таким образом для указателей члена парламента, не занимающего официального поста, которые никогда не будут раздаваться к другому объекту - использование scoped_ptr
. Если указатель будет роздан к чему-то еще (это включает использование их в контейнеры или если все, что Вы хотите сделать, передать владение и не сохранить или совместно использовать его) - использование shared_ptr
.
Я полагаю, что "переносятся, все указатели в shared_ptr
" должны действительно быть режимом по умолчанию и являются подходящим советом дать Вашим младшим кодерам. Однако в специальных случаях владения, которые Вы упомянули, auto_ptr
, является действительно более соответствующим, и его использование должно быть поощрено при таких обстоятельствах.
"Используйте shared_ptr
везде", хорошее правило по умолчанию и конечно хорошая начальная точка для обучающих людей об ответственном использовании интеллектуальных указателей. Однако это - не всегда лучший выбор.
, Если Вам не нужно совместно использованное владение, shared_ptr
, излишество: это должно выделить отдельный блок памяти для подсчета ссылок, который может повлиять на производительность, и это менее ясно мудрый документацией.
Лично, я использую std::auto_ptr
во многих местах, где boost::scoped_ptr
был бы также достаточен: например, содержа выделенный "куче" объект, прежде чем владение передается в другое место, где прошедшие операции могли бы бросить.
C++ 0x будет иметь std::unique_ptr
к дополнению std::shared_ptr
как лучшая альтернатива std::auto_ptr
. Когда это станет широко доступным, я начну использовать это.
Я полагаю, что это - лучшая практика, должен заменить всем использованием std::auto_ptr
boost::scoped_ptr
, если std::tr1::shared_ptr
не отвечает требованиям лучше, , если Вы не возражаете использовать Повышение. С другой стороны, это было, конечно, намеренным, что scoped_ptr
не был включен в TR1.
auto_ptr хорош в подписях, также. Когда функция берет auto_ptr<T>
значением, это означает, что это использует T
. Если функция возвращается auto_ptr<T>
, ясно, что это оставляет владение. Это может передать Ваши намерения о времени жизни.
, С другой стороны, с помощью scoped_ptr<T>
подразумевает, что Вы не хотите заботиться о времени жизни T
. Это также подразумевает, что можно использовать его в большем количестве мест. Оба интеллектуальных указателя являются допустимым выбором, у Вас могут, конечно, быть оба в единственной программе.