1

変更することになっているソース コードを (課題の一部として) 与えられましたが、コードの未変更バージョンをコンパイルすることができず、髪を引き裂いています。(明確にするために、このコードはハッシュテーブルに関する学校の課題用であり、これらのコンパイルエラーは課題の一部ではありません)

Visual Studio 2010 を使用してコンパイルしています。私は一日中これに取り組んでいて、まったくどこにも行きません!

一連の「LNK2005」エラーが発生します。

1>------ Build started: Project: Assignment10, Configuration: Debug Win32 ------
1>  hashmain.cpp
1>e:\google drive\cpsc 1160\labs\projects\assignment10\assignment10\hashtable.cpp(40): warning C4018: '<' : signed/unsigned mismatch
1>hashtable.obj : error LNK2005: "public: __thiscall HashTableSavitch::HashTable::HashTable(void)" (??0HashTable@HashTableSavitch@@QAE@XZ) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "public: virtual __thiscall HashTableSavitch::HashTable::~HashTable(void)" (??1HashTable@HashTableSavitch@@UAE@XZ) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "private: static int __cdecl HashTableSavitch::HashTable::computeHash(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?computeHash@HashTable@HashTableSavitch@@CAHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "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) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "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) already defined in hashmain.obj
1>E:\Google Drive\CPSC 1160\Labs\Projects\Assignment10\Debug\Assignment10.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

与えられたコードは次のとおりです。

ハッシュメイン.cpp

// 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;

int main()
{
    HashTable h;

    cout << "Adding dog, cat, turtle, bird" << endl;
    h.put("dog");
    h.put("cat");
    h.put("turtle");
    h.put("bird");
    cout << "Contains dog? "
        << h.containsString("dog") << endl;
    cout << "Contains cat? "
        << h.containsString("cat") << endl;
    cout << "Contains turtle? "
        << h.containsString("turtle") << endl;
    cout << "Contains bird? "
        << h.containsString("bird") << endl;

    cout << "Contains fish? "
        << h.containsString("fish") << endl;
    cout << "Contains cow? "
        << h.containsString("cow") << endl;

    return 0;
}

ハッシュテーブル.h

// This is the header file hashtable.h.  This is the interface
// for the class HashTable, which is a class for a hash table
// of strings.

#ifndef HASHTABLE_H
#define HASHTABLE_H

#include <string>
#include "listtools.h"

using LinkedListSavitch::Node;
using std::string;

namespace HashTableSavitch
{
  const int SIZE = 10;

  class HashTable
  {
   public:
        HashTable(); // Initialize empty hash table

        // Normally a copy constructor and overloaded assignment
        // operator would be included.  They have been omitted
        // to save space.

        virtual ~HashTable();  // Destructor destroys hash table

        bool containsString(string target) const;
        // Returns true if target is in the hash table,
        // false otherwise

        void put(string s);
        // Adds a new string to the hash table

   private:
        Node<string> *hashArray[SIZE];
        static int computeHash(string s);   // Compute hash value for string

  }; // HashTable
} // HashTableSavitch
#endif // HASHTABLE_H

ハッシュテーブル.cpp

// 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

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

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

listtools.cpp

//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

これは私の深みからは程遠いと思います。同様の問題/解決策をここやGoogleで見つけることができる他の場所に注ぎましたが、完全に困惑しています。

編集: Arcinde の要求に従って、次の#include "hashtable.cpp"ように hashmain.cppでコメントアウトしました。

#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 ==========
4

3 に答える 3

-1

あなたのhashmain.cppファイルで

// 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;

2 つのコメント行のコメントを外してみてください。

于 2015-07-25T00:02:29.137 に答える