0

我已经为分配创建了一个自定义映射(它是一个通用的模板化映射,它有自己的自定义迭代器和部分专业化),但是当应用程序尝试在它的代码中使用它时,我得到了对它所有函数的未定义引用。

我已经在类似的情况下查看了这里的其他问题,我猜我的命名空间或迭代器的位置有错误,或者导致应用程序找不到它的东西?

以下是相关代码:

        #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);
}

作为任务的一部分,我不能只更改上面的迭代器的使用,我必须自己创建它。

4

1 回答 1

0

导致错误消息的成员函数的实现不在map<string, V>. 我没有看到map::begin(),map::end()map::iterator::~iterator()任何地方的实现。大多数其他功能似乎都已实现(没有检查所有功能),但缺少这三个功能。map<K, V>在类内部实现begin()end(),但iterator::~iterator()那里也缺少实现。

于 2012-05-31T02:10:21.763 回答