Cでイテレータパターン
シリーズもの今回はイテレータ構造体。まずはイテレータインターフェイスに当たるヘッダファイルIterator.h
#ifndef ITERATOR_HEADER_FILE_INCLUDED__ #define ITERATOR_HEADER_FILE_INCLUDED__ /*! Iterator構造体 */ typedef struct Iterator_tag Iterator; /*! @brief 次の要素があるかどうかの判定 @param p:イテレータインスタンスを指すポインタ @retval 0: 次の要素無し @retval !0: 次の要素あり @attention !0の場合、nextが正常に実行できる @attention 実際の処理はコンクリートクラスにて実装のこと */ int hasNext(Iterator *p); /*! @brief 要素を取得し、次の要素を指すようにする @param p:イテレータインスタンスを指すポインタ @retval 取得した要素を指すポインタ @attention 戻り値の型はvoid *なので適切なポインタで受けること @attention 実際の処理はコンクリートクラスにて実装のこと */ void *next(Iterator *p); #endif /* End of ITERATOR_HEADER_FILE_INCLUDED__ */
んでこれを実装するBookShelfIteratorのヘッダファイルBookShelfIterator.h
#ifndef BOOK_SHELF_ITERATOR_HEADER_FILE_INCLUDED__ #define BOOK_SHELF_ITERATOR_HEADER_FILE_INCLUDED__ #include "Iterator.h" #include "BookShelf.h" /*! @brief BookShelfIteratorコンストラクタ @param p:BookShelfのインスタンスを指すポインタ @retval 生成したIteratorのインスタンスを指すポインタ @attention 戻り値のインスタンスはDisposeBookShelfで破棄すること */ Iterator *CreateBookShelfIterator(BookShelf *p); /*! @brief BookShelfIteratorのデストラクタ @param p: BookShelfIteratorインスタンスを指すポインタ */ void DisposeBookShelfIterator(Iterator *p); #endif
そんでもって、コンクリートイテレータであるBookShelfIterator.c。 BookShelfはBookを動的配列として保持していて、これをインデックス順に舐めるようなイテレータ実装とする。
#include "BookShelfIterator.h" #include "BookShelf.h" #include "Book.h" #include <stdlib.h> struct Iterator_tag{ BookShelf *pBookShelf; int index; }; int hasNext(Iterator *p) { if (p->index < GetLength(p->pBookShelf)) { return 1; } else { return 0; } } void *next(Iterator *p) { Book *pBook = GetBookAt(p->pBookShelf, p->index); p->index++; return pBook; } Iterator *CreateBookShelfIterator(BookShelf *pBookShelf) { Iterator *self = NULL; self = malloc(sizeof(Iterator)); if (self == NULL) { return NULL; } self->pBookShelf = pBookShelf; self->index = 0; return self; } void DisposeBookShelfIterator(Iterator *p) { free(p); }