Reputation: 3589
I'm typing out an example program from Absolute C++ and it keeps giving me this error:
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::HashTable()':
hashtableimp.cpp:(.text+0x0): multiple definition of `HashTableSavitch::HashTable::HashTable()'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x0): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::HashTable()':
hashtableimp.cpp:(.text+0x0): multiple definition of `HashTableSavitch::HashTable::HashTable()'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x0): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::~HashTable()':
hashtableimp.cpp:(.text+0x16): multiple definition of `HashTableSavitch::HashTable::~HashTable()'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x16): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::~HashTable()':
hashtableimp.cpp:(.text+0x16): multiple definition of `HashTableSavitch::HashTable::~HashTable()'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x16): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::~HashTable()':
hashtableimp.cpp:(.text+0x44): multiple definition of `HashTableSavitch::HashTable::~HashTable()'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x44): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::computeHash(std::string)':
hashtableimp.cpp:(.text+0x6a): multiple definition of `HashTableSavitch::HashTable::computeHash(std::string)'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x6a): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::containsString(std::string) const':
hashtableimp.cpp:(.text+0x7a): multiple definition of `HashTableSavitch::HashTable::containsString(std::string) const'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x7a): first defined here
/tmp/ccJfp4DM.o: In function `HashTableSavitch::HashTable::put(std::string)':
hashtableimp.cpp:(.text+0x8e): multiple definition of `HashTableSavitch::HashTable::put(std::string)'
/tmp/ccHuZlFl.o:hashtable.cpp:(.text+0x8e): first defined here
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'hashTable' failed
make: *** [hashTable] Error 1
I've reduced the program down to its pure basics but I still can't figure out what's going on. Can anyone help?
Makefile:
hashTable: listtools.h listtools.cpp hashtable.h hashtable.cpp hashtableimp.cpp
g++ listtools.h listtools.cpp hashtable.h hashtable.cpp hashtableimp.cpp -o hashTable
hashtable.h
#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();
virtual ~HashTable();
bool containsString(string target) const;
void put(string s);
private:
Node<string> *hashArray[SIZE];
static int computeHash(string s);
};
}
#endif
hashtable.cpp
#include <string>
#include "listtools.h"
#include "hashtable.h"
using LinkedListSavitch::Node;
using LinkedListSavitch::search;
using LinkedListSavitch::headInsert;
using std::string;
namespace HashTableSavitch {
HashTable::HashTable() {
}
HashTable::~HashTable() {
}
int HashTable::computeHash(string s) {
return 0;
}
bool HashTable::containsString(string target) const {
return true;
}
void HashTable::put(string s) {
}
} // HashTableSavitch
hashtableimp.cpp
#include <string>
#include <iostream>
#include "hashtable.h"
#include "listtools.cpp"
#include "hashtable.cpp"
using std::string;
using std::cout;
using std::endl;
using HashTableSavitch::HashTable;
int main() {
HashTable h;
cout << "Adding cat, dog, turtle, and bird" << endl;
h.put("cat");
h.put("dog");
h.put("turtle");
h.put("bird");
cout << "Contains cat? " << h.containsString("cat") << endl;
cout << "Contains dog? " << h.containsString("dog") << endl;
cout << "Contains turtle? " << h.containsString("turtle") << endl;
cout << "Contains bird? " << h.containsString("bird") << endl;
cout << "Contains cow? " << h.containsString("cow") << endl;
cout << "Contains fish? " << h.containsString("fish") << endl;
return 0;
}
listtools.h
#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);
template<class T>
void insert(Node<T>* afterMe, const T& theData);
template<class T>
void deleteNode(Node<T>* before);
template<class T>
void deleteFirstNode(Node<T>*& head);
template<class T>
Node<T>* search(Node<T>* head, const T& target);
} // LinkedListSavitch
#endif
Upvotes: 1
Views: 11053
Reputation: 10007
You should not #include
cpp's into the main hashtableimp.cpp
, if you want to list them on g++
command line.
Actually you have two options here:
#include
it one into another, so that it is effectively one file) — in such a case you need to list only this main file in g++
command lineg++
command line, but you do not need to #include
files with definitions (usually cpp) into other files.The reason is One Definition Rule: any function (with some exceptions) should be defined in one place in the whole program. If you #include
one cpps into anothers, and then compile all of them, you repeat definitions.
Usually the former approach is used for small programs, and the latter for lager projects. Even more commonly, in latter approach you usually compile each file one by one, and then link them together.
Also note that you do not usually need to list .h
files in the command line, they should not be compiled by themself, they are just to be #include
d into other .cpp
files so that the compiler knows the declaration of functions/objects/etc used there.
Upvotes: 12