C++ 错误LNK2005-我在这里做错了什么?

C++ 错误LNK2005-我在这里做错了什么?,c++,linker-errors,lnk2019,lnk2005,C++,Linker Errors,Lnk2019,Lnk2005,我已经得到了一些我应该修改的源代码(作为任务的一部分),但我无法编译未修改的代码版本,我正在抓狂。(需要明确的是-此代码用于学校哈希表作业,这些编译错误不是作业的一部分) 我正在使用VisualStudio2010进行编译。我整天都在做这件事,结果一事无成 我收到一系列“LNK2005”错误: 这会产生以下错误: 1>------ Build started: Project: Assignment10, Configuration: Debug Win32 ------ 1> h

我已经得到了一些我应该修改的源代码(作为任务的一部分),但我无法编译未修改的代码版本,我正在抓狂。(需要明确的是-此代码用于学校哈希表作业,这些编译错误不是作业的一部分)

我正在使用VisualStudio2010进行编译。我整天都在做这件事,结果一事无成

我收到一系列“LNK2005”错误:

这会产生以下错误:

1>------ Build started: Project: Assignment10, Configuration: Debug Win32 ------
1>  hashmain.cpp
1>hashtable.obj : error LNK2019: unresolved external symbol "class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > * __cdecl LinkedListSavitch::search<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$search@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@LinkedListSavitch@@YAPAV?$Node@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@0@PAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: bool __thiscall HashTableSavitch::HashTable::containsString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)const " (?containsString@HashTable@HashTableSavitch@@QBE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>hashtable.obj : error LNK2019: unresolved external symbol "void __cdecl LinkedListSavitch::headInsert<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > * &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$headInsert@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@LinkedListSavitch@@YAXAAPAV?$Node@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@0@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: void __thiscall HashTableSavitch::HashTable::put(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?put@HashTable@HashTableSavitch@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>E:\Google Drive\CPSC 1160\Labs\Projects\Assignment10\Debug\Assignment10.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
1>----构建已启动:项目:分配10,配置:调试Win32------
1> hashmain.cpp
1> hashtable.obj:错误LNK2019:未解析的外部符号“类LinkedListSavitch::Node*u cdecl LinkedListSavitch::search(类LinkedListSavitch::Node*,类std::basic_字符串常量&)”(??$search@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@@LinkedListSavitch@@YAPAV$Node@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@@0@PAV10@ABV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@函数“public:bool\uu thiscall HashTableSavitch::HashTable::containssString”中引用了2@@std@@@Z)(类标准::基本字符串)常量“(?)?containsString@HashTable@HashTableSavitch@@QBE\u NV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@@std@@@Z)
1> hashtable.obj:错误LNK2019:未解析的外部符号“void\u cdecl LinkedListSavitch::headInsert(类LinkedListSavitch::Node*&,类std::basic\u string const&)”(??$headInsert@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@@LinkedListSavitch@@YAXAAPAV$Node@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@@0@ABV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@函数“public:void\u thiscall HashTableSavitch::HashTable::put(类std::basic\u字符串)中引用了2@@std@@@Z)" (?put@HashTable@HashTableSavitch@@QAEXV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@@std@@@Z)
1> E:\Google Drive\CPSC 1160\Labs\Projects\Assignment10\Debug\Assignment10.exe:致命错误LNK1120:2个未解析的外部
======生成:0成功,1失败,0最新,0跳过==========

问题的根源似乎是您在没有实现的情况下实例化了模板函数(您的.h试图声明,而您的.cpp试图定义它们)

您有两种解决问题的方法:

  • 将所有内容从listtools.cpp移动到listtools.h,从而将模板实例化和实现移动到同一位置
  • 将listtools.cpp中的所有内容移动到新文件(listtoolssupport.h)中,并从listtools.h中删除声明
  • 使用选项1,我使用@n0rd和@Arcinde的指令将listtools.cpp的所有实现移动到listtools.h中。然后我完全删除了listtools.cpp,因为它现在什么都不做,并删除了.cpp的#includes

    listtools.h现在看起来像:

    //This is the header file listtools.h. This contains type definitions and
    //function declarations for manipulating a linked list to store data of any type T.
    //The linked list is given as a pointer of type Node<T>* which points to the 
    //head (first) node of the list. The implementation of the functions are given
    //in the file listtools.cpp.
    #ifndef LISTTOOLS_H
    #define LISTTOOLS_H
    #include <cstddef>
    namespace LinkedListSavitch
    {
    template<class T>
    class Node
    {
    public:
        Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink) { }
        Node<T>* getLink() const { return link; }
        const T& getData() const { return data; }
        void setData(const T& theData) { data = theData; }
        void setLink(Node<T>* pointer) { link = pointer; }
    private:
        T data;
        Node<T> *link;
    };
    
    template<class T>
    void headInsert(Node<T>*& head, const T& theData)
    {
        head = new Node<T>(theData, head);
    }
    //Precondition: The pointer variable head points to
    //the head of a linked list.
    //Postcondition: A new node containing theData
    //has been added at the head of the linked list.
    
    etc etc etc...
    
    //这是头文件listtools.h。它包含类型定义和
    //用于操作链表以存储任何类型T的数据的函数声明。
    //链表作为Node*类型的指针提供,指向
    //列表的头(第一个)节点。给出了函数的实现
    //在文件listtools.cpp中。
    #ifndef列表工具
    #定义列表工具
    #包括
    命名空间LinkedListSavitch
    {
    模板
    类节点
    {
    公众:
    节点(const T&theData,Node*theLink):数据(theData),链接(theLink){}
    Node*getLink()常量{return link;}
    const T&getData()const{return data;}
    void setData(const T&theData){data=theData;}
    void setLink(节点*指针){link=pointer;}
    私人:
    T数据;
    节点*链接;
    };
    模板
    无效标头插入(节点*&标头、常量和数据)
    {
    head=新节点(数据,head);
    }
    //前提条件:指针变量head指向
    //链表的头。
    //后置条件:包含数据的新节点
    //已添加到链接列表的开头。
    等等等等等等。。。
    

    “Unresolved External Symbol”(未解析的外部符号)基本上是说,当它转到链接时,它找不到节点的符号。

    问题的根源似乎是您在没有实现的情况下实例化了模板函数(您的.h试图声明,而您的.cpp试图定义它们)

    您有两种解决问题的方法:

  • 将所有内容从listtools.cpp移动到listtools.h,从而将模板实例化和实现移动到同一位置
  • 将listtools.cpp中的所有内容移动到新文件(listtoolssupport.h)中,并从listtools.h中删除声明
  • 使用选项1,我使用@n0rd和@Arcinde的指令将listtools.cpp的所有实现移动到listtools.h中。然后我完全删除了listtools.cpp,因为它现在什么都不做,并删除了.cpp的#includes

    listtools.h现在看起来像:

    //This is the header file listtools.h. This contains type definitions and
    //function declarations for manipulating a linked list to store data of any type T.
    //The linked list is given as a pointer of type Node<T>* which points to the 
    //head (first) node of the list. The implementation of the functions are given
    //in the file listtools.cpp.
    #ifndef LISTTOOLS_H
    #define LISTTOOLS_H
    #include <cstddef>
    namespace LinkedListSavitch
    {
    template<class T>
    class Node
    {
    public:
        Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink) { }
        Node<T>* getLink() const { return link; }
        const T& getData() const { return data; }
        void setData(const T& theData) { data = theData; }
        void setLink(Node<T>* pointer) { link = pointer; }
    private:
        T data;
        Node<T> *link;
    };
    
    template<class T>
    void headInsert(Node<T>*& head, const T& theData)
    {
        head = new Node<T>(theData, head);
    }
    //Precondition: The pointer variable head points to
    //the head of a linked list.
    //Postcondition: A new node containing theData
    //has been added at the head of the linked list.
    
    etc etc etc...
    
    //这是头文件listtools.h。它包含类型定义和
    //用于操作链表以存储任何类型T的数据的函数声明。
    //链表作为Node*类型的指针提供,指向
    //列表的头(第一个)节点。给出了函数的实现
    //在文件listtools.cpp中。
    #ifndef列表工具
    #定义列表工具
    #包括
    命名空间LinkedListSavitch
    {
    模板
    类节点
    {
    公众:
    节点(const T&theData,Node*theLink):数据(theData),链接(theLink){}
    Node*getLink()常量{return link;}
    const T&getData()const{return data;}
    void setData(const T&theData){data=theData;}
    void setLink(节点*指针){link=pointer;}
    私人:
    T数据;
    节点*链接;
    };
    模板
    无效标头插入(节点*&标头、常量和数据)
    {
    head=新节点(数据,head);
    }
    //前提条件:指针变量head指向
    //链表的头。
    //后置条件:包含数据的新节点
    //已在t处添加
    
    // This is the implementation file hashtble.cpp.
    // This is the implementation of the class HashTable.
    
    #include <string>
    #include "listtools.h"
    #include "hashtable.h"
    
    using LinkedListSavitch::Node;
    using LinkedListSavitch::search;
    using LinkedListSavitch::headInsert;
    using std::string;
    
    namespace HashTableSavitch
    {
       HashTable::HashTable()
       { 
        for (int i = 0; i < SIZE; i++)
        {
         hashArray[i] = NULL;
        }
       }
    
       HashTable::~HashTable()
       {
         for (int i=0; i<SIZE; i++)
         {
           Node<string> *next = hashArray[i];
           while (next != NULL)
           {
             Node<string> *discard = next;
         next = next->getLink( );
         delete discard;
           }
         }
       }
    
       int HashTable::computeHash(string s)
       {
        int hash = 0;
        for (int i = 0; i < s.length( ); i++) 
        {
         hash += s[i];
        }
        return hash % SIZE; 
       }
    
       bool HashTable::containsString(string target) const
       { 
        int hash = this->computeHash(target);
        Node<string>* result = search(hashArray[hash], target);
        if (result == NULL) 
           return false;
        else
           return true;
       }
    
       void HashTable::put(string s)
       {
        int hash = computeHash(s);
        if (search(hashArray[hash], s)==NULL)
        {
          // Only add the target if it's not in the list
          headInsert(hashArray[hash], s);
        }
       }
    
    } // HashTableSavitch
    
    //This is the header file listtools.h. This contains type definitions and
    //function declarations for manipulating a linked list to store data of any type T.
    //The linked list is given as a pointer of type Node<T>* which points to the 
    //head (first) node of the list. The implementation of the functions are given
    //in the file listtools.cpp.
    #ifndef LISTTOOLS_H
    #define LISTTOOLS_H
    
    namespace LinkedListSavitch
    {
        template<class T>
        class Node
        {
        public:
            Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink){}
            Node<T>* getLink( ) const { return link; }
            const T& getData( ) const { return data; }
            void setData(const T& theData) { data = theData; }
            void setLink(Node<T>* pointer) { link = pointer; }
        private:
            T data;
            Node<T> *link;
        };
    
        template<class T>
        void headInsert(Node<T>*& head, const T& theData);
        //Precondition: The pointer variable head points to
        //the head of a linked list.
        //Postcondition: A new node containing theData
        //has been added at the head of the linked list.
    
        template<class T>
        void insert(Node<T>* afterMe, const T& theData);
        //Precondition: afterMe points to a node in a linked list.
        //Postcondition: A new node containing theData
        //has been added after the node pointed to by afterMe.
    
        template<class T>
        void deleteNode(Node<T>* before);
        //Precondition: The pointers before point to nodes that has 
        //at least one node after it in the linked list. 
        //Postcondition: The node after the node pointed to by before
        //has been removed from the linked list and its storage 
        //returned to the freestore.
    
        template<class T>
        void deleteFirstNode(Node<T>*& head);
        //Precondition: The pointers head points to the first
        //node in a linked list; with at least one node.
        //Postcondition: The node pointed to by head has been removed
        //for the linked list and its storage returned to the freestore.
    
        template<class T>
        Node<T>* search(Node<T>* head, const T& target);
        //Precondition: The pointer head points to the head of a linked list.
        //The pointer variable in the last node is NULL. head (first) node
        //head (first) node has been defined for type T. 
        //(== is used as the criterion for being equal).
        //If the list is empty, then head is NULL.
        //Returns a pointer that points to the first node that 
        //is equal to the target. If no node equals the target, 
        //the function returns NULL.
    }//LinkedListSavitch
    
    #endif //LISTTOOLS_H
    
    //This is the implementation file listtools.cpp. This file contains 
    //function definitions for the functions declared in listtools.h.
    
    #include <cstddef>
    #include "listtools.h"
    
    namespace LinkedListSavitch
    {
        template<class T>
        void headInsert(Node<T>*& head, const T& theData)
        {
            head = new Node<T>(theData, head);
        }
    
        template<class T>
        void insert(Node<T>* afterMe, const T& theData)
        {
            afterMe->setLink(new Node<T>(theData, afterMe->getLink( )));
        }
    
        template<class T>
        void deleteNode(Node<T>* before)
        {
            Node<T> *discard;
            discard = before->getLink( );
            before->setLink(discard->getLink( ));
            delete discard;
        }
    
        template<class T>
        void deleteFirstNode(Node<T>*& head)
        {
            Node<T> *discard;
            discard = head;
            head = head->getLink( );
            delete discard;
        }
    
        //Uses cstddef:
        template<class T>
        Node<T>* search(Node<T>* head, const T& target)
        {
            Node<T>* here = head;
    
            if (here == NULL) //if empty list
            {
                return NULL;
            }
            else
            {
                while (here->getData( ) != target && here->getLink( ) != NULL)
                    here = here->getLink( );
    
                if (here->getData( ) == target)
                    return here;
                else
                    return NULL;
            }
        }
    
    }//LinkedListSavitch
    
    #include <string>
    #include <iostream>
    #include "listtools.cpp"    // Your compiler may compile separately
    #include "hashtable.h"
    //#include "hashtable.cpp"  // Your compiler may compile separately
    using std::string;
    using std::cout;
    using std::endl;
    using HashTableSavitch::HashTable;
    
    1>------ Build started: Project: Assignment10, Configuration: Debug Win32 ------
    1>  hashmain.cpp
    1>hashtable.obj : error LNK2019: unresolved external symbol "class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > * __cdecl LinkedListSavitch::search<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$search@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@LinkedListSavitch@@YAPAV?$Node@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@0@PAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: bool __thiscall HashTableSavitch::HashTable::containsString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)const " (?containsString@HashTable@HashTableSavitch@@QBE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
    1>hashtable.obj : error LNK2019: unresolved external symbol "void __cdecl LinkedListSavitch::headInsert<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > * &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$headInsert@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@LinkedListSavitch@@YAXAAPAV?$Node@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@0@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: void __thiscall HashTableSavitch::HashTable::put(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?put@HashTable@HashTableSavitch@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
    1>E:\Google Drive\CPSC 1160\Labs\Projects\Assignment10\Debug\Assignment10.exe : fatal error LNK1120: 2 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    
    //This is the header file listtools.h. This contains type definitions and
    //function declarations for manipulating a linked list to store data of any type T.
    //The linked list is given as a pointer of type Node<T>* which points to the 
    //head (first) node of the list. The implementation of the functions are given
    //in the file listtools.cpp.
    #ifndef LISTTOOLS_H
    #define LISTTOOLS_H
    #include <cstddef>
    namespace LinkedListSavitch
    {
    template<class T>
    class Node
    {
    public:
        Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink) { }
        Node<T>* getLink() const { return link; }
        const T& getData() const { return data; }
        void setData(const T& theData) { data = theData; }
        void setLink(Node<T>* pointer) { link = pointer; }
    private:
        T data;
        Node<T> *link;
    };
    
    template<class T>
    void headInsert(Node<T>*& head, const T& theData)
    {
        head = new Node<T>(theData, head);
    }
    //Precondition: The pointer variable head points to
    //the head of a linked list.
    //Postcondition: A new node containing theData
    //has been added at the head of the linked list.
    
    etc etc etc...
    
    // Program to demonstrate use of the HashTable class
    
    #include <string>
    #include <iostream>
    //#include "listtools.cpp"  // Your compiler may compile separately
    #include "hashtable.h"
    //#include "hashtable.cpp"  // Your compiler may compile separately
    using std::string;
    using std::cout;
    using std::endl;
    using HashTableSavitch::HashTable;