2010-12-01 12 views
5

私はここに物事のカップルを把握しようとしています:インクリメント演算子/イテレータの実装

  1. どのように私は次のノードへのポインタを持つノードクラスのインクリメント演算子を書くのですか?
  2. 以下のようなクラスのイテレータを実装するにはどうすればよいですか?

    #include <iostream> 
    #include <vector> 
    using namespace std; 
    
    template <typename T> 
    class Node { 
    public: 
        Node(int i=0):val(i) {} 
        Node*& operator++(int i=0) {return next;}; 
    
        T val; 
        Node *next; 
    }; 
    
    //================================================ 
    int main() { 
    
        Node<int> *head, *tmp1, *tmp2; 
    
        tmp1 = new Node<int>(0); 
        head = tmp1; 
    
        for (int i=1; i<10; ++i) { 
    
         tmp2 = new Node<int>(i); 
         tmp1->next = tmp2; 
         tmp1 = tmp2; 
        } 
    
        while (head != NULL) { 
    
         cout << head->val << " '"; 
         head = head->operator++(0); //How do I make it work with ++head;? 
        } 
    } 
    

これは、演算子のオーバーロードやイテレータを実証するための好例ではありません。

+3

あなたはできません。 headはポインタであり、++演算子はポインタのために組み込み/定義されています。頭がオブジェクトまたはオブジェクトへの参照であった場合は、それを行うことができます。 –

+0

うーん。イテレータを実装するためのあらゆるリンクを知っていますか?ありがとうございます – blueskin

+0

この質問への回答を見ることができます:http://stackoverflow.com/questions/3582608/how-to-correctly-implement-custom-iterators-and-const-iterators –

答えて

10

Nodeクラスにoperator++を実装していません。 iterator用に実装します。イテレータークラスは別のクラスでなければなりません。

そして、(valTているので、あなたのコンストラクタはT、ないintを受け入れるべき)仮定を行うことによって、あなたのテンプレートを台無しにしないでください。また、オペレータ++へのパラメータintを無視しないでください。これは、プリインクリメントの実装とポストインクリメントの実装を区別するために使用されるダミーです。

template <typename T> 
struct Node { 
    T val; 
    Node *next; 

    Node(const T& t = T()) : val(t) {} 
}; 

template <typename T> 
struct node_iter { 
    Node<T>* current; 
    node_iter(Node<T>* current): current(current) {} 

    const node_iter& operator++() { current = current->next; return *this; } 
    node_iter operator++(int) { 
     node_iter result = *this; ++(*this); return result; 
    } 
    T& operator*() { return current->val; } 
}; 

int main() { 
    // We make an array of nodes, and link them together - no point in 
    // dynamic allocation for such a simple example. 
    Node<int> nodes[10]; 
    for (int i = 0; i < 10; ++i) { 
     nodes[i] = Node<int>(i); 
     nodes[i].next = (i == 9) ? nodes + i + 1 : 0; 
    } 

    // we supply a pointer to the first element of the array 
    node_iter<int> test(nodes); 
    // and then iterate: 
    while (test.current) { 
     cout << *test++ << " "; 
    } 
    // Exercise: try linking the nodes in reverse order. Therefore, we create 
    // 'test' with a pointer to the last element of the array, rather than 
    // the first. However, we will not need to change the while loop, because 
    // of how the operator overload works. 

    // Exercise: try writing that last while loop as a for loop. Do not use 
    // any information about the number of nodes. 
} 

これは、適切なリンクリストクラスを作り、適切なデータのカプセル化、メモリ管理などを提供するからオフに長い、長い道のりが容易ではないではまだです。そのため、標準ライブラリが提供しています。車輪を再構築しないでください。

+0

私はこれを投稿した後でそれを実現しました。実際にイテレータを実装する方法を理解しようとしていましたが、これは悪い例です。 QListはSTLリストよりもうまく実装されていると思います。私はそのようなものを実装しようとします。ありがとうKarl – blueskin

+2

http://en.literateprograms.org/Singly_linked_list_%28C_Plus_Plus%29より役に立ちます – blueskin

+1

演算子++()がconst参照を返し、演算子++(int)が値を返すのはなぜですか? –

関連する問題