Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
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 ");
}
}
}
Самый раздражающий синтаксический анализ
Это связано с тем, что известно как самый раздражающий синтаксический анализ "C++". В основном что-либо, что может быть интерпретировано компилятором как объявление функции, будет интерпретироваться как объявление функции.
Другой экземпляр той же проблемы:
std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
v
интерпретируется как объявление функции с 2 параметрами.
обходное решение должно добавить другую пару круглых скобок:
std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());
Или, если у Вас есть C++ 11 и инициализация списка (также известный как универсальная инициализация) доступный:
std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
С этим, нет никакого способа, которым это могло быть интерпретировано как объявление функции.
Тот же синтаксис используется для объявления функции - например, функция object
, не беря параметров и возвращаясь MyObject
Поскольку это - рассматриваемый как объявление для функции:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
Я предполагаю, компилятор не знал бы если этот оператор:
объект MyObject ();
вызов конструктора или прототип функции, объявляя функцию, названную объект с типом MyObject возврата и никакими параметрами.
Поскольку компилятор думает, что это - объявление функции, которая не берет аргументов и возвращает экземпляр MyObject.
Вы могли также использовать более подробный способ конструкции:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
В C++ 0x это также допускает auto
:
auto object1 = MyObject();
auto object2 = MyObject(object1);
Как упомянуто много раз, это - объявление. Это - тот путь к обратной совместимости. Одна из многих областей C++, которые являются глупыми/непоследовательными/болезненными/поддельными из-за его наследия.