2016-12-25 69 views
0

我有一個賦值,我需要在其中創建模板類LinkedList和Traversible。 Class Traversible需要是一個接口,它聲明瞭某些集合類的索引和迭代函數。我不完全知道如何爲迭代器創建接口,以便LinkedList可以使用它。我想這樣聲明迭代函數的接口

template <class T, class U> 
class ITraversible { 
public: 
    virtual U begin() noexcept = 0; 
    virtual U end() noexcept = 0; 
    virtual T& operator[](int) = 0; 
}; 

,然後在鏈表的頭文件,我會做:

template <class T> 
class LinkedList : public ITraversible<T,typename LinkedList<T>::iterator> { 
    struct node { 
     T data; 
     node* next, *prev; 
     explicit node(const T&); 
     void connect(node*); 
    }; 

    node *head, *tail; 
    int n; 

public: 
    /*************************ITERATOR************************/ 
    class iterator : public std::iterator<std::bidirectional_iterator_tag, node*> { 
     typename LinkedList<T>::node* itr; 
     explicit iterator(node*) noexcept; 
     friend class LinkedList; 
    public: 
     iterator& operator++(); 
     iterator operator++(int); 
     iterator& operator--(); 
     iterator operator--(int); 
     bool operator==(const iterator&) const noexcept; 
     bool operator!=(const iterator&) const noexcept; 
     T& operator*() const noexcept; 
     T& operator->() const noexcept; 
    }; 
    /**********************************************************/ 

    LinkedList() noexcept; 
    LinkedList(std::initializer_list<T>); 
    LinkedList(const LinkedList&); 
    LinkedList(LinkedList&&) noexcept; 
    ~LinkedList() noexcept; 
    LinkedList& operator=(LinkedList) noexcept; 

    template <class A> 
    friend void swap(LinkedList<A>&, LinkedList<A>&); 

    void add(const T&); 
    void removeAt(int); 
    int size() const noexcept; 
    bool operator==(const LinkedList&) const noexcept; 
    bool operator!=(const LinkedList&) const noexcept; 
    virtual T& operator[](int) override; 
    virtual iterator begin() noexcept override; 
    virtual iterator end() noexcept override; 
}; 

但隨後Traversable的模板有兩個參數,它應該只有一個。 這是我應該做的嗎?請記住我是模板和迭代器的新手。

+0

爲什麼你認爲Traversible模板必須有一個參數? –

+0

在assigment它說,我們需要編寫類穿越 Nebeski

回答

0

當創建一個接口時,你需要確定返回的靜態類型。這些行爲可能動態地不同,但在返回指針或引用時,除了使用子類型關係外,您不能改變其類型。

就我個人而言,我認爲這個練習對於C++環境來說是不明智的。它可能可能使用Java或C#時有一定意義。然而,類似的行爲可以得到。一個草圖將會是這樣的(儘管這應該起作用它會很慢):

template <typename T> 
struct iterator_base { 
    virtual iterator_base() {} 
    virtual iterator_base<T>* do_clone() = 0; 
    virtual T&    do_value() = 0; 
    virtual void    do_next() = 0; 
    virtual bool    do_equal() = 0; 
    // other operations to implement operator--, operator[], ... 
}; 
template <typename It> 
class iterator: iterator_base<typename std::iterator_traits<It>::value_type> { 
    typedef typename std::iterator_traits<It>::value_type> type; 
    It it; 
    iterator_base<type>* do_clone() { return new iterator<It>(*this); } 
    type& do_value() { return *this->it; } 
    void do_next() { ++this->it; } 
    bool do_equal(iterator_base<type>* other) { 
     return this->it == static_cast<iterator<It>>(other)->it; 
    } 
}; 

template <typename T> 
class poly_iterator { 
    std::unique_ptr<iterator_base<T>> ptr; 
public: 
    poly_iterator(iterator_base<T>* ptr): ptr(ptr) {} 
    poly_iterator(poly_iterator const& other): ptr(other.ptr->clone()) {} 
    poly_iterator& operator= (poly_iterator other) { 
     other.swap(this); 
     return *this; 
    } 
    void swap(poly_iterator& other) { swap(this->ptr, other.ptr); } 
    T& operator*() { return this->ptr->value(); } 
    T* operator->() { return &this->operator*(); } 
    poly_iterator& operator++() { this->ptr->next(); return *this; } 
    poly_iterator operator++(int) { 
     poly_iterator rc(*this); 
     this->operator++(); 
     return rc; 
    } 
    bool operator== (poly_iterator const& other) { 
     return this->ptr->equal(other.ptr.ptr()); 
    } 
    bool operator!= (poly_iterator const& other) { 
     return !(*this == other); 
    } 
    // other operations 
}; 
// define a suitable specialization of std::iterator_traits<poly_iterator<T>> 

template <typename T> 
class ITraversible { 
    virtual iterator_base<T>* do_begin() = 0; 
    virutal iterator_base<T>* do_end() = 0; 

public: 
    poly_iterator<T> begin() { return this->do_begin(); } 
    poly_iterator<T> end() { return this->do_end(); } 
    // other operations 
}; 

template <typename T> 
class List: public ITraversible<T> { 
    std::list<T> list; 

    iterator_base<T>* do_begin() { 
     return iterator<std::list<T>::iterator>(list.begin()); 
    } 
    iterator_base<T>* do_end() { 
     return iterator<std::list<T>::iterator>(list.end()); 
    } 
public: 
    // whatever is needed to fill the list 
};