c #arrays #pointers #iterator
#c #массивы #указатели #итератор
Вопрос:
Я пытаюсь создать класс итератора на c для класса, который имеет 2d-массив размером 8×8 в качестве основного элемента данных. Я хочу выполнить итерацию по столбцу 2d-массива.
Я пытаюсь думать об этом с точки зрения того, как пишется класс векторного итератора.
Как мне создать этот класс итератора? Должен ли конструктор принимать двойной указатель (** obj)? Предполагая, что я это сделаю, как я буду выполнять приращения при перегрузке оператора для двойного указателя?
Это то, что у меня есть
class Iterator
{
public:
Iterator(Board **obj)
{
ptr = obj;
}
Iteratoramp; operator ()
{
ptr ;
}
private:
Board **ptr;
};
Комментарии:
1. Мошенничество, как ад. C в значительной степени предпочитает порядок следования строк, поэтому, если данные должны быть доступны в основном в порядке следования столбцов, поверните данные на 90 градусов, чтобы строки и столбцы поменялись местами, и предоставьте оператор индекса, который представляет данные в ожидаемом порядке пользователя в тех редких случаях, когда им нужно отобразить их с помощьюправильные координаты.
Ответ №1:
Во-первых, ваша данная реализация НЕВЕРНА. Когда вы увеличиваете свой указатель, вы увеличиваете его на одну доску, а не на одну позицию в доске. Это совсем не то, что вы хотите.
Если вы собираетесь правильно реализовать итераторы, вам нужно начать с содержащего класса — предполагая, что вы на самом деле говорите об итераторах, чтобы вы могли сделать что-то вроде:
for (int i: myBoard) { }
и компилятор знает, что делать.
class Board {
public:
class ForwardIterator { ... };
class ReverseIterator { ... };
ForwardIterator begin() { ... }
ForwardIterator end() { ... }. // Should return one position past the end
ReverseIterator rbegin() { ... }
ReverseIterator rend() { ... }. // One position before beginning
};
Это только начало. Вам также нужны версии const. Вероятно, вы можете очистить это с помощью шаблонов, но вы начинаете видеть — это не обязательно тривиально.
Под капотом итератор может работать так, как вы хотите, чтобы он работал. Вы можете сохранить int row, col
, например, и просто переместить их соответствующим образом. В самой простой форме это то, что я бы сделал.
Вам также нужны operator= и operator!=, чтобы вы могли сравнивать итераторы для определения начала или окончания прошлого.
Не забудьте также реализовать:
int amp; operator*() { return board[row][col]; }
Полный ответ, выполненный правильно, выходит за рамки Stack Overflow . Это неплохая ссылка: https://internalpointers.com/post/writing-custom-iterators-modern-cpp . Но поиск в Google для «написания итераторов c » даст множество полезных ссылок для подробных деталей.