Мне был предоставлен некоторый исходный код (как часть задания), который я должен изменить, но я не могу получить немодифицированную версию кода для компиляции, и я разорву свои волосы. (Чтобы быть ясным - этот код предназначен для школьного задания в хэш-таблицах, эти ошибки компиляции не часть задания)ошибка LNK2005 - Что я здесь делаю неправильно?
Я использую визуальную студию 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)" ([email protected]@@[email protected]) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "public: virtual __thiscall HashTableSavitch::HashTable::~HashTable(void)" ([email protected]@@[email protected]) 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> >)" ([email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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 " ([email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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> >)" ([email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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 ==========
Вот код, я был дан:
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;
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;
}
hashtable.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
hashtable.cp р
// 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, но я полностью в тупике.
Edit: По просьбе 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 &)" ([email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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 " ([email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected][email protected]@@[email protected]@@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 &)" ([email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected]@YA[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function "public: void __thiscall HashTableSavitch::HashTable::put(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" ([email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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 ==========
Реализация функции шаблона должна быть видимой в точке создания шаблона. Что по существу означает, что весь код шаблона должен находиться в файле .h. – n0rd
Я раскодировал файлы с расширением .cpp в hashmain.cpp, что значительно изменило выход ошибки. – b1skit
Попробуйте комментировать только '#include" hashtable.cpp "и оставить' #include "listtools.cpp" 'uncommented, который должен исправить его. И скажите тому, кто написал это, что @ n0rd сказал ... это довольно плохо организовано. – Arcinde