Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Я бы поместил их в анонимное пространство имен в файле CPP. Это делает их закрытыми для реализации и в то же время делает их видимыми для не-членских функций, которые являются частью реализации (например, operator<<
).
Если строки предназначены для просмотра пользователями класса, поместите их в класс. В противном случае скройте их в безымянном пространстве имен файла реализации.
Я думаю, что реальная проблема заключается в следующем: действительно ли строки используются только для реализации класса, или они используются где-то еще.
Чтобы быть действительно придирчивым, я бы постарался сохранить интерфейс класса настолько чистым, насколько это возможно, поэтому, если строки имени файла не должны представлять интереса для «внешнего» мира. Я бы скрыл их внутри только в .cpp-файле. И в этом случае я не думаю, что буду беспокоиться о пространстве имен, а просто сохраню «статичность» (т. Е. Внутреннюю по отношению к .cpp-файлу).
Однако, если вы сделаете это, нужно быть осторожным: я бы не рекомендовал использовать статические объекты std :: string, вместо этого используйте static char *. Причина этого связана с потенциальными проблемами с порядком инициализации. Допустим, у вас есть статический экземпляр класса, конструктор которого ссылается на строку A::f1
. Нет никакой гарантии, что A::f1
был построен, и вы получите крах, или, что еще хуже, не крах, а поддельные данные.
Отслеживание ошибок порядка инициализации может быть довольно неприятным, и все может выглядеть хорошо в одном проекте, но тогда вы можете построить другой проект с использованием тех же библиотек, и небольшие различия в порядке ссылок приведут к эта ошибка загадочно появляется.
Статические члены класса.
Если они используются в нескольких местах одним классом, обычно проще держать вещи организованными - и позже найти, где вы все определили - если вы оставите их определенными в классе, который их использует. Определение их на месте затрудняет их поиск и последующее изменение. И я бы выбрал конкретный класс для анонимного пространства имен для более чистого определения и использования класса.
Если они используются только в одном файле, то нет необходимости показывать их внешнему миру, включая их в заголовочный файл.
Если они используются и всегда будут использоваться только в одном месте, то на самом деле нет никакой причины не просто записывать их как литералы, где их нужно использовать.
Если бы они использовались в нескольких местах в cpp, я бы выбрал анонимное пространство имен.
Другой вариант, который вы не упомянули, - это определить их как статические переменные внутри cpp. это несколько эквивалентно опции анонимного пространства имен и более похоже на C, чем на C ++.
Если он используется только в файле класса .cpp, нет необходимости использовать какое-либо пространство имен, просто скажите:
const std::string f1 = "filename1";
const std::string f2 = "filename2";
const std::string f3 = "filename3";
Чрезмерное использование пространств имен - это новая вещь - я могу Я лично вижу привлекательность.
Из трех вариантов, единственный, который вы должны избегать, это # 1. Не используйте магические куки в вашем коде. Поместив константы либо в пространство имен, либо в класс, вы упростите расширение и поддержку своего кода в будущем.
Если ваши константы имеют глобальный характер, то между 2 и 3 это мало что значит. Важно то, что вы выбираете один и придерживаетесь его. Но если у вас есть константы, которые применяются к определенному классу, то они должны быть частью этого класса.
Лично я бы использовал пространство имен для большинства вещей.
Просто поместите строки const в область действия файла в файле реализации, анонимное пространство имен не обязательно ограничивать их использование только этим классом.
Стандарт C ++ 003 C.1.2 Раздел 3: основные понятия
Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage
Примечание. Анонимное пространство имен помогает уменьшить конфликты имен.