2016-11-21 98 views
2

以下代碼使用自定義迭代器打印0到9之間的數字。我g++ -std=c++11 -o test test.cppC++自定義迭代器構造函數

#include <iostream> 

class some_class; 

class some_class_iterator : public std::iterator<std::forward_iterator_tag, int>{ private:  
    friend class some_class; 
    int pointed; 
    some_class_iterator(int _pointed): pointed(_pointed){ 
     std::cout << "over here" << std::endl; 
    } 

public: 
    int poitned; 

    int operator*(){ 
     return pointed; 
    } 

    const some_class_iterator& operator++(){ 
     pointed++; 
     return *this; 
    } 

    bool operator!=(const some_class_iterator& other) const { 
     return this->pointed != other.pointed; 
    } 

}; 

class some_class{ 
public: 
    typedef some_class_iterator iterator; 

    iterator begin(){ 
     return some_class_iterator(0); 
    } 

    iterator end(){ 
     return some_class_iterator(10); 
    } 

}; 


int main(){ 

    some_class a; 
    for (some_class::iterator i = a.begin(); i != a.end(); ++i) std::cout << *i << std::endl; 

} 

編譯但是,輸出是不是我預計爲over here打印多次。 例如實際輸出爲

over here 
over here 
0 
over here 
1 
over here 
2 
over here 
3 
over here 
4 
over here 
5 
over here 
6 
over here 
7 
over here 
8 
over here 
9 
over here 

那麼,誰是造成對這裏的構造函數的調用?

我的實際問題是二叉搜索樹的迭代器,在構造函數中,我創建了一個FIFO遍歷,根據(in,pre,post)打印節點,因此多次調用構造函數的代價很高。

回答

3

您的循環的每次迭代都會調用a.end(),這將創建一個新的迭代器並「在此處」打印。你可以打印出_pointed的值來看看這個。 (第一個「在這裏」來自begin調用)。

+0

* High five!* ...和一些填充文本。 –

+0

哎呀..那是一個失敗的問題...... –

+1

@k_kaz Nah,你對未來的調試技術有了一些啓發,所以這最終是一種勝利。 –

1

每次檢查for循環中的條件時,都會調用end(),它構造一個新的迭代器。

如果您將pointed_添加到您的調試輸出中,它可以幫助追蹤這樣的事情。所以可以將打印輸出添加到其他調用中,並且還可以在調試器中逐步完成。

爲了避免它,你可以在for循環之前緩存結尾,但這很奇怪,並且不適合循環迭代器的通常模式。一個更好的解決方案可能是將end存儲爲類中的成員,並讓end()返回對其的引用,或者查看是否可以找到一種方法在實際程序中降低迭代器構造的成本。

+0

如果some_class :: end()返回這個你引用的const引用,那麼這是一個更好的設計嗎? –

+0

@k_kaz是的,這將是一個不錯的選擇。 –