2010-12-17 11 views
1

我試圖在C++中實現雙向鏈表現在我正在添加迭代器功能。編譯沒有錯誤,直到我添加這些方法(可能)變爲罰款:C++問題:「未解析的外部」UberList <int> :: Iter :: Iter()'從C: USERS HOME CPPTEST UBERLIST.OBJ引用「

template<class T> 
typename UberList<T>::Iter UberList<T>::begin() const 
{ 
    Iter it; 
    it.curr = head; 
    return it; 
} 


template<class T> 
typename UberList<T>::Iter UberList<T>::end() const 
{ 
    Iter it; 
    it.curr = tail; 
    return it; 
} 

,然後我得到這個:

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland 
UberList2.cpp: 
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland 
Error: Unresolved external 'UberList<int>::Iter::Iter()' referenced from C:\USERS\HOME\CPPTEST\UBERLIST2.OBJ 

我在這裏看到,它可能是一個鏈接的問題類似的問題,但我不確定這是否是我的情況,因爲我只使用一個文件。我很感激任何關於這個奇怪問題的幫助。

這裏是我班的全碼:

#include <iostream> 

using namespace std; 

template<class T> 
class UberList 
{ 
    friend class Iter; 

    private: 


    struct Node 
    { 
      friend class Iter; 
      T data; 

      Node *prev; 
      Node *next; 

      Node() 
        :data(0), prev(0), next(0) 
      { 
      } 

      Node(const T& d, Node *p, Node *n) 
        : data(d), prev(p), next(n) 
      { 
      } 

    }; 

    public: 
    class Empty 
    { 
    }; 
    class BadIter 
    { 
    }; 

    class Iter 
    { 
      friend class UberList; 

      public: 

      //constructors 
      Iter(); 
      Iter(Node *n) 
      { 
        curr = n; 
      } 


      T& operator*() 
      { 
        return curr->data; 
      } 


      Iter& operator++() 
      { 
        if(curr == 0) 
          throw BadIter(); 
        curr = curr->next; 
        return *this; 
      } 

      Iter& operator--() 
      { 
        if(curr == 0) 
          throw BadIter(); 
        curr = curr->prev; 
        return *this; 
      } 


      bool operator==(const Iter& it) 
      { 
        return curr == it.curr; 
      } 
      bool operator!=(const Iter& it) 
      { 
        return curr != it.curr; 
      } 


      private: 
      Node *curr; 
    }; 


    UberList() 
      :length(0), head(0), tail(0) 
    { 
    } 
    ~UberList(); 


    int size() 
    { 
      return length; 
    } 

    bool empty() 
    { 
      return length == 0; 
    } 

    void pushBack(const T& elem); 
    void popBack(); 
    void pushFront(const T& elem); 
    void popFront(); 

    Iter begin() const; 
    Iter end() const; 

    Iter erase(typename UberList<T>::Iter curr); 
    void insertBefore(const T& elem, Iter curr); 
    private: 

    int length; 
    Node *head; 
    Node *tail; 
}; 
template<class T> 
typename UberList<T>::Iter UberList<T>::begin() const 
{ 
    Iter it; 
    it.curr = head; 
    return it; 
} 

template<class T> 
typename UberList<T>::Iter UberList<T>::end() const 
{ 
    Iter it; 
    it.curr = tail; 
    return it; 
} 



template<class T> 
UberList<T>::~UberList() 
{ 
    while(head != 0) 
    { 
      popBack(); 
    } 
} 


template<class T> 
void UberList<T>::pushBack(const T& elem) 
{ 
    if(empty()) 
    { 

      head = tail = new Node(elem, 0, 0); 
    } 
    else 
    { 

      tail = tail -> next = new Node(elem, tail, 0); 
    } 
    ++length; 


} 


template<class T> 
void UberList<T>::popBack() 
{ 

    if(empty()) 
      throw Empty(); 


    if(length == 1) 
    { 
      delete head; 
      head = tail = 0; 

    } 
    else 
    { 

      tail = tail->prev; 

      delete tail->next; 

      tail->next = 0; 

    } 
} 

template<class T> 
typename UberList<T>::Iter UberList<T>::erase(typename UberList<T>::Iter curr) 
{ 
    if(curr.curr == 0) 
      throw BadIter(); 
    if(curr.curr == head) 
    { 
      popFront(); 
    } 
    else if(curr.curr == tail) 
    { 
      popBack(); 
    } 
    else 
    { 

      curr.curr->prev->next = curr.curr->next; 

      curr.curr->next->prev = curr.curr->prev; 

      Node *t = curr.curr->next; 

      delete curr.curr; 
      return Iter(t); 

    } 


} 

template<class T> 
void UberList<T>::insertBefore(const T& elem, Iter curr) 
{ 
     if(curr.curr == 0) 
       throw BadIter(); 
     if(curr.curr == head) 
     { 
       pushfront(elem); 
     } 
     else 
     { 

       curr.curr->prev = curr.curr->prev->next = new Node(elem, curr.curr->prev, curr.curr); 
     } 
} 

int main() 
{ 

     int a; 
     UberList<int> ulist; 
     while (cin >> a) 
     { 
       ulist.pushBack(a); 
     } 
     for (UberList<int>::Iter it = ulist.begin(); it != ulist.end(); ++it) 
     { 
       cout << *it << " "; 
     } 

     return 0; 
} 
+0

沒有足夠的信息,但我猜你是在錯誤的文件中聲明瞭模板函數。模板函數必須進入頭文件。 – fho 2010-12-17 12:43:18

+0

我在一個.cpp文件中寫了我的課。這是它:http://pastebin.com/k5ZrYBVR – Chris 2010-12-17 12:52:40

回答

3

國際熱核實驗堆默認構造函數聲明,但沒有定義。將第48行改爲

Iter(){curr = NULL; }

+0

yaaay!有用!非常感謝你! – Chris 2010-12-17 13:01:28