忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

反復子を自分で作ってみる

ども・・・・・・・・・・・・和佐田雅史です。
今回はイテレータについてです。

イテレータと言うのは反復子の事で、listやmapコンテナをfor文でポインタによる参照( のようなもの )を行いたい時に使います。

std::list< T >::iterator it = List.begin();

と言う感じですね。
しかし、自分でコンテナを作った時にiteratorはどう作ればよいでしょうか?

基本的には定義したコンテナクラスの中にローカルクラスとして定義するのが一般的です。

template< class T > class Freelist
{
// 実装

// ローカルクラスとして定義
class iterator : public std::iterator<.....>
};

ですが一々コンテナを作る時に定義するのははっきり言ってめんどくさいのでtemplateで作っておくと便利です。


//============================================
// コンテナ作成時の反復子
//
//
//
//============================================

#ifndef _ITERATOR_HPP_
#define _ITERATOR_HPP_

#include <iterator>

namespace Alumina
{

// friendの為の仮定義
template< typename Type , typename value_type > class iterator;
template< typename Type , typename value_type > class const_iterator;


//=============================================
// 通常iterator
//
//
//=============================================
template< typename Type , typename value_type > class iterator : public std::iterator<std::bidirectional_iterator_tag, value_type, void>
{
public:
 iterator() : _ptr(0) {}

 iterator(Type* ptr) : _ptr(ptr){}

 // ジェネリック要素へのアクセス
 Type& operator*() const {return *_ptr;}
 Type* operator->() const {return _ptr;}


 // 真偽判定
 bool operator==(const iterator& rhs) const {return _ptr == rhs._ptr;}
 bool operator!=(const iterator& rhs) const {return _ptr != rhs._ptr;}

//=============================================
//
// 演算子によるポインタ演算
//
//=============================================
 iterator& operator++() {_ptr = _ptr->_next; return *this;}
 iterator& operator--() {_ptr = _ptr->_prev; return *this;}
 iterator operator++(int i) { iterator temp = *this; ++*this; return temp; }
 iterator operator--(int i) { iterator temp = *this; --*this; return temp; }

protected:

 // メンバ
 Type* _ptr;

 friend class Type;
 friend class const_iterator;
};

//===============================================
// const_iterator
//
//
//===============================================
template< typename Type , typename value_type > class const_iterator : public std::iterator<std::bidirectional_iterator_tag, value_type, void>
{
public:
 const_iterator() : _ptr(0){}
 const_iterator(const iterator& it) : _ptr(it._ptr) {}
 const_iterator(const Type* ptr) : _ptr(ptr) {}

 const Type& operator*() const {return *_ptr;}
 const Type* operator->() const {return _ptr;}

 bool operator==(const const_iterator& rhs) const {return _ptr == rhs._ptr;}
 bool operator!=(const const_iterator& rhs) const {return _ptr != rhs._ptr;}

 //=============================================
 //
 // 演算子によるポインタ演算
 //
 //=============================================
 
 const_iterator& operator++() {_ptr = _ptr->_next; return *this;}
 const_iterator& operator--() {_ptr = _ptr->_prev; return *this;}
 const_iterator operator++(int i) { const_iterator temp = *this; ++*this; return temp; }
 const_iterator operator--(int i) { const_iterator temp = *this; --*this; return temp; }

protected:
 const Type* _ptr;

 friend class Type;
};


}
#endif


長くなりましたが、使用例を以下に示します。


// LISTNODE 型を管理するリストコンテナ
template < typename LISTNODE , template< class > class Interfase = ListType > class FreeList
{
public:

 // 実装インターフェース設定
 typedef Interfase< LISTNODE > LIST;

 // それに伴った反復子を定義
 typedef Alumina::iterator< LIST , LIST > iterator;
 typedef Alumina::const_iterator< LIST , LIST > const_iterator;

.........................

};

このように定義するだけでiteratorが使えるようになります。
便利ですね。


それではお疲れ様でした。

拍手[0回]

PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

無題

  • by ZAKI
  • 2008/02/20(Wed)01:37
  • Edit
ちょwww区切り用の「=」コメント長すぎるww
他の記事がずれるから直してくれ。

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]