2012-05-31 54 views
0

我已經創建了一個賦值的自定義映射(它是一個帶有自己的自定義迭代器和部分專用化的通用模板映射),但是我得到了未定義的所有函數引用,應用程序試圖在它的代碼中使用它。C++未定義的引用自定義映射迭代器函數

我對這裏的其他問題有類似的情況,我猜我的名字空間或迭代器的位置有錯誤,或者導致應用程序找不到它?

下面是相關代碼:

 #ifndef MAP_H 
#define MAP_H 

#define SIZE 101 

#include <string> 

using std::string; 

namespace myMap{ 


    ////////////////////START TEMPLATE////////////////////// 

    template<class K, class V> 
    class map 
    { 
     private: 
      typedef struct SNode{ 
       K first; 
       V second; 
       SNode* next; 
      } Node; 

      Node** hashArray; 
      Node* head; 
      Node* tail; 
      Node* lastEntry; 

     public: 
      map(); 
      ~map(); 

      V generateHash(K first); 
      void addPair(K first, V second); 
      void checkHeadTail(); 
      int count(K key); 

      V& operator[](K first); 

      class iterator 
      { 
       private: 
        Node* currentNode; 
        K first; 
        V second; 
       public: 
        iterator(); 
        iterator(Node* pos); 
        ~iterator(); 

        void operator++(int); 
        Node* operator->(); 
        bool operator!=(iterator other); 
      }; 

      iterator begin(){iterator iter(head); return iter;} 
      iterator end(){iterator iter(NULL); return iter;} 
    }; 

    template<class K, class V> 
    map<K, V>::map() 
    { 
     hashArray = new Node*[SIZE]; 
     for(unsigned int i = 0; i < SIZE; i++){ 
      hashArray[i] = NULL; 
     } 

     head = NULL; 
     tail = NULL; 
     lastEntry = NULL; 
    } 

    template<class K, class V> 
    map<K, V>::~map() 
    { 
     for(unsigned int i = 0; i < SIZE; i++){ 
      if(hashArray[i] != NULL){ 
       Node* tmpNode = hashArray[i]; 
       Node* currentNode = hashArray[i]; 
       while(currentNode){ 
        currentNode = currentNode->next; 
        delete tmpNode; 
        tmpNode = currentNode; 
       } 
      } 
     } 

     delete [] hashArray; 
    } 

    template<class K, class V> 
    V map<K, V>::generateHash(K first) 
    { 
     V hash = 0; 
     for(unsigned int j = 0; j < first.length(); j++){ 
      hash += first[j]; 
     } 
     return hash % SIZE; 
    } 

    template<class K, class V> 
    void map<K, V>::checkHeadTail() 
    { 
     if(hashArray[0] != NULL){ 
      head = hashArray[0]; 
      tail = hashArray[0]; 
     } 

     Node* currentNode = *hashArray; 
     while(currentNode->next){ 
      currentNode = currentNode->next; 
     } 
     tail = currentNode; 
    } 

    template<class K, class V> 
    void map<K, V>::addPair(K first, V second) 
    { 
     Node* newEntry = new Node; 
     newEntry->first = first; 
     newEntry->second = second; 
     newEntry->next = NULL; 

     V hash = generateHash(first); 

     if(hashArray[hash] == NULL){ 
      hashArray[hash] = newEntry; 
      lastEntry = newEntry; 
     } else { 
      Node* currentNode = hashArray[hash]; 
      while(currentNode->next){ 
       if(currentNode->first == first){ 
        currentNode->second += second; 
        lastEntry = currentNode; 
        return; 
       } 
       currentNode = currentNode->next; 
      } 
      if(currentNode->first == first){ 
       currentNode->second += second; 
       lastEntry = currentNode; 
       return; 
      } else { 
       currentNode->next = newEntry; 
       lastEntry = newEntry; 
       return; 
      } 
     } 
     checkHeadTail(); 
    } 

    template<class K, class V> 
    V& map<K, V>::operator[](K first) 
    { 
     V second = 0; 
     addPair(first, second); 

     return lastEntry->second; 
     checkHeadTail(); 
    } 

    template<class K, class V> 
    int map<K, V>::count(K key) 
    { 
     V hash = generateHash(key); 
     if(hashArray[hash] != NULL){ 
      return true; 
     } 
     return false; 
    } 

    template<class K, class V> 
    void map<K, V>::iterator::operator++(int) 
    { 
     currentNode = currentNode->next; 
    } 

    template<class K, class V> 
    bool map<K, V>::iterator::operator!=(map::iterator other) 
    { 
     if(first == other->first) return false; return true; 
    } 

    template<class K, class V> 
    typename map<K, V>::Node* map<K, V>::iterator::operator->() 
    { 
     return currentNode; 
    } 

    template<class K, class V> 
    map<K, V>::iterator::iterator() 
    { 
     currentNode = NULL; 
    } 

    template<class K, class V> 
    map<K, V>::iterator::iterator(Node* pos) 
    { 
     currentNode = pos; 
    } 

    ////////////////////SPECIALISATION/////////////////////////////// 

    template<class V> 
    class map<string, V> 
    { 
     private: 
      typedef struct SNode{ 
       string first; 
       V second; 
       SNode* next; 
      } Node; 

      Node** hashArray; 
      Node* head; 
      Node* tail; 
      Node* lastEntry; 

     public: 
      map(); 
      ~map(); 

      V generateHash(string first); 
      void addPair(string first, V second); 
      void checkHeadTail(); 
      V count(string key); 

      V& operator[](string first); 

      class iterator 
      { 
       private: 
        Node* currentNode; 
        string first; 
        V second; 
       public: 
        iterator(); 
        iterator(Node* pos); 
        ~iterator(); 

        void operator++(V); 
        Node* operator->(); 
        bool operator!=(iterator other); 
      }; 

      iterator begin(); 
      iterator end(); 
    }; 

    template<class V> 
    map<string, V>::map() 
    { 
     hashArray = new Node*[SIZE]; 
     for(unsigned int i = 0; i < SIZE; i++){ 
      hashArray[i] = NULL; 
     } 

     head = NULL; 
     tail = NULL; 
     lastEntry = NULL; 
    } 

    template<class V> 
    map<string, V>::~map() 
    { 
     for(unsigned int i = 0; i < SIZE; i++){ 
      if(hashArray[i] != NULL){ 
       Node* tmpNode = hashArray[i]; 
       Node* currentNode = hashArray[i]; 
       while(currentNode){ 
        currentNode = currentNode->next; 
        delete tmpNode; 
        tmpNode = currentNode; 
       } 
      } 
     } 

     delete [] hashArray; 
    } 

    template<class V> 
    V map<string, V>::generateHash(string first) 
    { 
     unsigned long hash = 0; 
     for(unsigned int j = 0; j < first.length(); j++){ 
      hash += first[j]; 
     } 
     return (V) hash % SIZE; 
    } 

    template<class V> 
    void map<string, V>::checkHeadTail() 
    { 
     if(hashArray[0] != NULL){ 
      head = hashArray[0]; 
      tail = hashArray[0]; 
     } 

     Node* currentNode = *hashArray; 
     while(currentNode->next){ 
      currentNode = currentNode->next; 
     } 
     tail = currentNode; 
    } 

    template<class V> 
    void map<string, V>::addPair(string first, V second) 
    { 
     Node* newEntry = new Node; 
     newEntry->first = first; 
     newEntry->second = second; 
     newEntry->next = NULL; 

     V hash = generateHash(first); 

     if(hashArray[hash] == NULL){ 
      hashArray[hash] = newEntry; 
      lastEntry = newEntry; 
     } else { 
      Node* currentNode = hashArray[hash]; 
      while(currentNode->next){ 
       if(currentNode->first == first){ 
        currentNode->second += second; 
        lastEntry = currentNode; 
        return; 
       } 
       currentNode = currentNode->next; 
      } 
      if(currentNode->first == first){ 
       currentNode->second += second; 
       lastEntry = currentNode; 
       return; 
      } else { 
       currentNode->next = newEntry; 
       lastEntry = newEntry; 
       return; 
      } 
     } 
     checkHeadTail(); 
    } 

    template<class V> 
    V& map<string, V>::operator[](string first) 
    { 
     V second = 0; 
     addPair(first, second); 

     return lastEntry->second; 
     checkHeadTail(); 
    } 

    template<class V> 
    V map<string, V>::count(string key) 
    { 
     V hash = generateHash(key); 
     if(hashArray[hash] != NULL){ 
      return true; 
     } 
     return false; 
    } 

    template<class V> 
    map<string, V>::iterator::iterator() 
    { 
     currentNode = NULL; 
    } 

    template<class V> 
    map<string, V>::iterator::iterator(Node* pos) 
    { 
     currentNode = pos; 
    } 

    template<class V> 
    void map<string,V>::iterator::operator++(V) 
    { 
     currentNode = currentNode->next; 
    } 

    template<class V> 
    typename map<string, V>::Node* map<string, V>::iterator::operator->() 
    { 
     return currentNode; 
    } 

    template<class V> 
    bool map<string, V>::iterator::operator!=(map::iterator other) 
    { 
     if(first == other->first) return false; return true; 
    } 

} // END NAMESPACE 

#endif // MAP_H 

錯誤:當應用程序試圖使用迭代器作爲這樣

undefined reference to `myMap::map<std::string, int>::begin()' 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::end()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::begin()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::end()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 
undefined reference to `myMap::map<std::string, int>::iterator::~iterator()'| 

誤差修改發生:

map<string, int>::iterator iter; 
for(iter = wordsCount.begin(); iter != wordsCount.end(); iter++){ 
    orderedList.addWord(iter->first, iter->second); 
} 

隨着任務的一部分,我不允許將迭代器的使用僅改變爲我必須創建的實現我自己。

+0

對於哪些功能,您是否收到錯誤消息?你的例子錯過了'map'函數的所有實現。只有'map :: iterator'的成員函數被實現。 –

+0

我已經更新了代碼以反映整個文件。感謝您的快速回復:) –

+0

在您發佈的內容中,我看不到'begin()','end()'和'〜iterator()'的實現,您確定這是整個文件嗎? –

回答

0

導致錯誤消息的成員函數的實現不在map<string, V>的頭文件中。我沒有看到任何地方的map::begin()map::end()map::iterator::~iterator()的實現。其他大部分功能似乎都已經實施(沒有全部檢查),但是這三項功能都沒有完成。 map<K, V>在課程內部實現了begin()end(),但iterator::~iterator()的實現也在那裏丟失。

+0

啊,那些是我得到重複錯誤的3,謝謝。我會看看我能否修復它們。我沒有意識到我刪除了專業化中那些函數的內聯聲明。 –

+0

Ah - 'begin()'和'end()'在類中定義。我錯過了:) –

+0

好吧,我現在編譯好了,但它只是一旦我啓動它就崩潰了...大聲笑 –