Другое событие 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));
}
Это - более или менее ошибка в компиляторе. Обратите внимание, что в более свежих версиях компилятора это предупреждение не становится брошенным (по крайней мере, в 4,3, это не делает). Наличие деструктора быть защищенным и невиртуальное, абсолютно законно в Вашем случае.
См. здесь для превосходной статьи Herb Sutter на предмете. От статьи:
Инструкция № 4: деструктор базового класса должен быть или общедоступным и виртуальным, или защищенный и невиртуальным.
Некоторые комментарии к этому ответу касаются более раннего ответа, который я дал, который был неправильным.
А защитил средства деструктора, которыми это можно только назвать от базового класса, не через удаляют. Это означает, что ITest* не может быть непосредственно удален, только производный класс может. Производный класс может хотеть виртуальный деструктор. Нет ничего неправильно с Вашим кодом вообще.
Однако, так как Вы не можете локально отключить предупреждение в GCC, и у Вас уже есть vtable, Вы могли считать просто создание деструктора виртуальным так или иначе. Это будет стоить Вам 4 байтов за программу (не на экземпляр класса), максимум. Так как Вы, возможно, дали Вашему производному классу виртуальный dtor, можно найти, что он ничего не стоит Вам.
Если Вы настаиваете на том, чтобы делать это, разрешение и передаете -Wno-non-virtual-dtor
GCC. Это предупреждение, кажется, не включено по умолчанию, таким образом, Вы, должно быть, включили его с -Wall
или -Weffc++
. Однако я думаю, что это - полезное предупреждение, потому что в большинстве ситуаций это было бы ошибкой.
Это - интерфейсный класс, таким образом, разумно, что Вы не должны удалять объекты, реализовывая тот интерфейс через тот интерфейс. Общий падеж этого является интерфейсом для объектов, созданных фабрикой, которая должна быть возвращена к фабрике. (Имеющие объекты содержат указатель на свою фабрику, могло бы быть довольно дорогим).
я согласился бы с наблюдением, что GCC жалуется. Вместо этого это должно просто предупредить при удалении ITest*. Это - то, где реальная опасность находится.
Мое персональное представление состоит в том, что Вы были бы, делая корректную вещь, и компилятор повреждается. Я отключил бы предупреждение (локально в файле, который определяет интерфейс), если это возможно,
я нахожу, что использую этот шаблон (маленький 'p') довольно много. На самом деле я нахожу, что моим интерфейсам более свойственно защитить dtors, чем это для них для имения общедоступных. Однако я не думаю, что это на самом деле настолько распространено идиома (это не становится говорившим о так очень), и я предполагаю назад, когда предупреждение было добавлено к GCC, было уместно попытаться осуществить более старое 'dtor, должно быть виртуальным, если у Вас есть виртуальные функции' правило. Лично я обновил то правило к 'dtor, должно быть виртуальным, если Вы имеете виртуальные функции и хотите, чтобы пользователи были в состоянии еще удалить экземпляры интерфейса через интерфейс, dtor должен быть защищен и не виртуальный' давным-давно;)
Если деструктор является виртуальным, он удостоверяется, что деструктор базового класса также называют передним выполнением очистки, иначе некоторые утечки могут следовать из того кода. Таким образом, необходимо удостовериться, что программа не имеет таких предупреждений (предпочтительно никакие предупреждения вообще).
Если бы у Вас был код в одном из ITest
методы, которые попробовали к delete
самом (плохая идея, но законный), деструктор производного класса не назвали бы. Необходимо все еще сделать деструктор виртуальным, даже если Вы никогда не намереваетесь удалить полученный экземпляр через указатель базового класса.