Как мне создать класс итератора для итерации по указателю 2d-массива?

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 » даст множество полезных ссылок для подробных деталей.