2011-03-16 38 views
1

我創建了一個容器列表的小實現,它基於測試main()執行某些功能。我的列表<T>實施有什麼問題?

我想添加一些額外的功能。主要是一個operator[]和一個reverse()函數,它向後顯示列表中的數字。

這是我的代碼,每一句評論都是昨天添加的。

#include <iostream> 
#include <algorithm> 

using namespace std; 

template <class T> class Link; 
template <class T> class List_iterator; 
template <class T> class Reverse_iterator; 

template <class T> 
class List 
{ 
public: 
    typedef List_iterator<T> iterator; 

    List(); 
    List(const List<T> & l); 
    ~List(); 

    bool empty() const; 
    unsigned int size() const; 
    T & back() const; 
    T & front() const; 
    void push_front(const T & x); 
    void push_back(const T & x); 
    void pop_front(); 
    void pop_back(); 
    iterator begin() const; 
    iterator end() const; 
    iterator rbegin() const;//REVERSE BEGIN 
    iterator rend() const; //REVERSE END 
    void insert(iterator pos, const T & x); 
    void erase(iterator & pos); 
    List<T> & operator=(const List<T> & l); 
    List<T> & operator[] (unsigned int x);//OPERATOR [] 
    iterator reverse() const; //REVERSE 

protected: 
    Link<T> * first_link; 
    Link<T> * last_link; 
    unsigned int my_size; 
}; 

template <class T> 
List<T>::List() 
{ 
     first_link = 0; 
     last_link = 0; 
     my_size = 0; 
} 

template <class T> 
List<T>::List(const List & l) 
{ 
     first_link = 0; 
     last_link = 0; 
     my_size = 0; 
     for (Link<T> * current = l.first_link; current != 0; current = current -> next_link) 
       push_back(current -> value); 
} 

template <class T> 
typename List<T>::iterator List<T>::begin() const 
{ 
    return iterator(first_link); 
} 

template <class T> 
typename List<T>::iterator List<T>::end() const 
{ 
    return iterator (last_link); 
} 

//RBEGIN 
template <class T> 
typename List<T>::iterator List<T>::rbegin() const 
{ 
    return iterator (last_link); 
} 

//REND 
template <class T> 
typename List<T>::iterator List<T>::rend() const 
{ 
    return iterator(first_link); 
} 

template <class T> 
class Link 
{ 
private: 
    Link(const T & x): value(x), next_link(0), prev_link(0) {} 

    T value;  
    Link<T> * next_link; 
    Link<T> * prev_link; 

    friend class List<T>; 
    friend class List_iterator<T>; 
}; 

template <class T> class List_iterator 
{ 
public: 
    typedef List_iterator<T> iterator; 

    List_iterator(Link<T> * source_link): current_link(source_link) { } 
    List_iterator(): current_link(0) { } 
    List_iterator(List_iterator<T> * source_iterator): current_link(source_iterator.current_link) { } 

    T & operator*(); 
    iterator & operator=(const iterator & rhs); 
    bool operator==(const iterator & rhs) const; 
    bool operator!=(const iterator & rhs) const; 
    iterator & operator++(); 
    iterator operator++(int); 
    iterator & operator--(); 
    iterator operator--(int); 

protected: 
    Link<T> * current_link; 

    friend class List<T>; 
}; 

template <class T> 
T & List_iterator<T>::operator*() 
{ 
     return current_link -> value; 
} 

template <class T> 
List_iterator<T> List_iterator<T>::operator++(int) 
{ 

} 

template <class T> 
List_iterator<T> & List_iterator<T>::operator--() 
{ 
    current_link = current_link -> prev_link; 
    return * this; 
} 

template <class T> 
List_iterator<T> & List_iterator<T>::operator=(const iterator & rhs) 
{ 
///??? 
} 

template <class T> 
List_iterator<T> List_iterator<T>::operator--(int) 
{ 

} 

template <class T> 
List_iterator<T> & List_iterator<T>::operator++() 
{ 
     current_link = current_link -> next_link; 
     return *this; 
} 

template <class T> 
void List<T>::push_back(const T & x) 
{ 
    Link<T> * new_link = new Link<T> (x); 
    if (first_link == 0) 
    first_link = last_link = new_link; 
    else 
    { 
    new_link->prev_link = last_link; 
     last_link->next_link = new_link;  
     last_link = new_link; 
    } 
    my_size++; 
} 

template <class T> 
List <T>::~List() 
{ 
    Link <T> * first = first_link; 
    while (first != 0) 
    { 
    Link <T> * next = first->next_link; 
     delete first; 
    first = next; 
    } 
} 

template<class T> 
bool List_iterator<T>::operator==(const iterator & rhs) const 
{ 
    return (this->current_link == rhs.current_link); 
} 

template <class T> 
bool List_iterator<T>::operator!=(const iterator & rhs) const 
{ 
    return !(*this == rhs); 
} 

//REVERSE ITERATOR 
template <class T> class Reverse_iterator 
{ 
public: 
    typedef Reverse_iterator<T> riterator; 

    Reverse_iterator(Link<T> * source_link): current_link(source_link) { } 
    Reverse_iterator(): current_link(0) { } 
    Reverse_iterator(List_iterator<T> * source_iterator): current_link(source_iterator.current_link) { } 

    T & operator*(); 
    riterator & operator=(const riterator & rhs); 
    bool operator==(const riterator & rhs) const; 
    bool operator!=(const riterator & rhs) const; 
    riterator & operator++(); 
    riterator operator++(int); 
    riterator & operator--(); 
    riterator operator--(int); 

protected: 
    Link<T> * current_link; 

    friend class List<T>; 
}; 

template <class T> 
T & Reverse_iterator<T>::operator*() 
{ 
     return current_link -> value; 
} 

template <class T> 
Reverse_iterator<T> Reverse_iterator<T>::operator++(int) 
{ 

} 

template <class T> 
Reverse_iterator<T> & Reverse_iterator<T>::operator--() 
{ 
    current_link = current_link -> next_link; 
    return * this; 
} 

template <class T> 
Reverse_iterator<T> & Reverse_iterator<T>::operator=(const riterator & rhs) 
{ 
//??? 
} 

template <class T> 
Reverse_iterator<T> Reverse_iterator<T>::operator--(int) 
{ 

} 

template<class T> 
bool Reverse_iterator<T>::operator==(const riterator & rhs) const 
{ 
    return (this->current_link == rhs.current_link); 
} 

template <class T> 
bool Reverse_iterator<T>::operator!=(const riterator & rhs) const 
{ 
    return !(*this == rhs); 
} 


//REVERSE FUNCTION 
template <class T> 
List_iterator<T> List<T>::reverse() const 
{ 
    iterator i, j; 
    i = begin(); 
    j = end(); 
    for(; i != j; j++, j--) 
    { 
      T value = *j; 
     *j = *i; 
     *i = value; 
    } 
} 

//OPERATOR [] 
template <class T> 
List<T> & List<T>:: operator[] (unsigned int x) 
{ 
    Link<T> * current = first_link; 
    for(int i = 0; i != x && i < my_size; i++) 
    current = current -> next_link; 
    return current -> value; 
    delete current; 
} 


//REVERSE ITERATOR OPERATOR ++() 
template <class T> 
Reverse_iterator<T> & Reverse_iterator<T>::operator++() 
{ 
    current_link = current_link -> prev_link; 
    return *this; 
} 

int main() 
{ 
    List<int> l; 

    l.push_back(44); 
    l.push_back(33); 
    l.push_back(11); 
    l.push_back(22); 

    List<int> m(l); 
    cout << "This is the original list" << endl; 
    List<int>::iterator original(m.begin()); 
    while (original != m.end()) { 
     cout << *original << endl; 
     ++original; 

    //cout << l[4]; //Not working 

    //m.reverse(); 
    //cout << m;//Also Not working 
    } 
} 

我在尋求幫助:

  • 寫我operator=()功能,這是目前空白。
  • 瞭解爲什麼main()中的最後幾行不能正常工作(我知道它們已被註釋掉),請查看我的operator[]定義和我的reverse()函數。

在此先感謝。

+1

這裏有太多的代碼。請只發布您有疑問的部分。另外,試着讓你的問題更具體,也許考慮把它分成幾個問題。 – 2011-03-16 14:50:04

+0

基本上,只是想知道是否有人可以幫助145行上的[]運算符,因爲我的實現目前還沒有工作,並想知道是否有人可以查看我的反向函數272行,並告訴我爲什麼它會在終端中返回一個錯誤,我雖然那個功能很紮實,我不知道要改變什麼。對不起,這個問題太長了。 – mikhailovich 2011-03-16 15:01:12

+0

查看我的答案,下面是對運營商的幫助[] – razlebe 2011-03-16 15:17:42

回答

1

關於List<T>::operator[]

我相信你operator[]的主要問題是,它的返回類型List<T>&而非T&。您希望您的operator[]返回對T的引用,而不是對整個列表的引用。 Operator<<不知道如何處理List<T>,所以它抱怨。

此外:

  • deleteoperator[]是無法訪問的代碼。 (除了作爲錯誤的行爲 - 你爲什麼要刪除的鏈接?)

  • operator[]產生一些警告,因爲iintmy_sizeunsigned。很容易糾正,見下文。

  • 想一想,如果像@stefaanv所提到的那樣,當列表中只有4個項目(從0開始的集合索引,請記住,因此[4]是第五個項目時,會有人要求myList [4])。您當前的邏輯,myList中[3]將返回,而不是 - 在所述條件下仔細尋找循環

這裏就是我想operator[]應該像:

template <class T> 
T& List<T>:: operator[] (unsigned int x) 
{ 
    if(x > (my_size - 1) 
     || x < 0) 
    { 
     // throw a suitable exception - index out of bounds 
    } 

    Link<T> * current = first_link; 
    for(unsigned int i = 0; i != x && i < my_size; i++) 
     current = current -> next_link; 
    return current -> value; 
} 

...和見IdeOne上的here


關於List<T>::reverse

首先第一件事情 - 從List_iterator<T> List<T>::reverse()看到錯誤,你首先需要解決您的main()

//m.reverse(); 
    //cout << m;//Also Not working 

注意,m是List<int>型的,所以那cout行試圖調用< < opertaor在你的List<T>類 - 但沒有'一,所以你會得到錯誤。

  1. 它遍歷列表逐項您List<T>
  2. main()類似於while循環迴路,更換cout行定義operator<<:您可以通過兩種解決這個問題。

一旦你做了其中一個,你會看到來自reverse()函數的真實錯誤信息。首先,你已經聲明反向返回List_iterator<T> - 但它目前不返回任何東西!

希望有幫助!祝你好運。

+0

我沒有能力投票給你,但非常感謝你,這非常有幫助。 – mikhailovich 2011-03-16 15:25:01

+0

不客氣。 – razlebe 2011-03-16 15:35:38

1
iterator begin() const; 
iterator end() const; 
iterator rbegin() const;//REVERSE BEGIN 
iterator rend() const; //REVERSE END 

我不認爲你必須讓這些函數爲const。

如果你編寫兩套這些函數,一個用於非const,另一個用於const對象,則會更好。

//first set for non-const objects! 
iterator begin(); 
iterator end(); 
iterator rbegin(); 
iterator rend(); 

//second set for const objects! 
const_iterator begin() const; 
const_iterator end() const; 
const_iterator rbegin() const; 
const_iterator rend() const; 

這是C++定義beginend功能的標準方式!

0

錯誤反向:()

j = end(); 

到底應該分容器後,所以Ĵ應該如果容器不爲空,有一個額外的遞減。

for(; i != j; j++, j--) 
  1. J ++必須是我++
  2. 爲元素的偶數,我將永遠是相同的AJ,使用I>Ĵ

錯誤主:

cout << l[4]; 

您的列表中只有4個元素,而您正在引用第5個元素,所以這不應該起作用。

+0

我改變了反向功能,但我仍然不知道如何在終端中正確顯示它。使用'm.reverse(); cout << m;'不起作用。至於operator []函數,我忘了它應該以[0]開頭,所以我將其更改爲[3],但是我在讀取「'在成員函數中」列表&List :: operator [] (unsigned int)[with T = int]': 323:從這裏實例化 294:錯誤:類型爲'List '的引用無效初始化''我確信這是因爲我的操作符=函數,任何想法是什麼函數應該看起來像什麼? – mikhailovich 2011-03-16 15:11:48