Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
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 ");
}
}
}
Можно сделать это использование двух циклов. Первое объявляет итератор с именем, которое является функцией контейнерной переменной (и можно сделать это более ужасным, если Вы волнуетесь по поводу конфликтов со своим собственным кодом). Второе объявляет переменную значения.
#define ci(container) container ## iter
#define foreach_value(var, container) \
for (typeof((container).begin()) ci(container) = container.begin(); \
ci(container) != container.end(); ) \
for (typeof(ci(container)->second)* var = &ci(container)->second; \
ci(container) != container.end(); \
(++ci(container) != container.end()) ? \
(var = &ci(container)->second) : var)
При помощи того же условия выхода из цикла внешний цикл только происходит однажды (и если Вы удачливы, оптимизирован далеко). Кроме того, Вы стараетесь не звонить-> второй на итераторе, если карта пуста. Это - та же причина тернарного оператора в инкременте внутреннего цикла; в конце мы просто оставляем var в последнем значении, так как на это не сошлются снова.
Вы могли встроить ci (контейнер), но я думаю, что он делает макрос более читаемым.
Вы искали бы BOOST_FOREACH - они уже сделали всю работу для Вас!
Если Вы действительно хотите к самокрутке, можно объявить блок где угодно в C++, который решает вопрос объема с промежуточным устройством хранения данных itr-> второй...
// Valid C++ code (which does nothing useful)
{
int a = 21; // Which could be storage of your value type
}
// a out of scope here
{
int a = 32; // Does not conflict with a above
}
STL преобразовывает функцию, также делает что-то подобное.
Аргументы (в порядке):
Для очень простого примера Вы могли использовать для своей выгоды каждый символ в строке:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main(int argc, char* argv[]) {
std::string s("my lowercase string");
std::transform(s.begin(), s.end(), s.begin(), toupper);
std::cout << s << std::endl; // "MY LOWERCASE STRING"
}
Кроме того, существует также накапливать функция, которая позволяет некоторым значениям быть сохраненными между вызовами к функциональному объекту. накопитесь не изменяет данные во входном контейнере, как имеет место с преобразованием.
Вы могли определить шаблонный класс, который берет тип mymap как шаблонный параметр и действует как итератор по значениям путем перегрузки * и->.
Вы думали о пользовании библиотеками Boost? У них есть a foreach
макрос, реализованный, который, вероятно, более устойчив, чем что-нибудь, что Вы запишете... и, существует также transform_iterator
который, казалось бы, смог бы использоваться, чтобы сделать часть второго извлечения того, что Вы хотите.
К сожалению, я не могу сказать Вам точно, как использовать его, потому что я не знаю достаточно C++ :) Этот поиск Google поднимает некоторые многообещающие ответы: comp.lang.c ++. модерируемый, Повышение transform_iterator вариант использования.
Повышение:: For_each является безусловно Вашим лучшим выбором. Изящная вещь состоит в том, что то, что они на самом деле дают Вам, является макро-BOOST_FOREACH (), который можно затем перенести и #define к тому, что действительно требуется назвать им в коде. Большинство все выберут старый добрый "foreach", но другие магазины могут иметь различные стандарты кодирования, таким образом, это соответствует тому мышлению. Повышение также имеет много других положительных героев для разработчиков C++! Определенно стоящий использования.
#define foreach(var, container) for (typeof((container).begin()) var = (container).begin(); var != (container).end(); ++var)
Нет никакого typeof в C++..., как это компилирует для Вас? (это, конечно, не портативно),