2013-10-08 4 views
0

У меня есть набор файлов, которые скомпилированы с make-файлом, чтобы создать отдельную цепочку хеширования. Программа работает до тех пор, пока я не добавлю код для вставки, удаления и содержит функции. Я вытащил код прямо из книги, но я получаю неоднозначную ошибку, которую я не могу понять, и надеюсь, что кто-то здесь может помочь ее идентифицировать. Я не отправлял всю программу, потому что я везу обоснованное предположение, что причина ошибки не будет найдена за пределами этого кода (но я могу ошибаться)Неопределенная ошибка символа в C++ Hashing Program

Ошибка в вопросе:

Undefined      first referenced 
symbol        in file 
hash(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)hashApp.o 

Кроме того, не уверен, если это необходимо, но если я пытаюсь скомпилировать файл .cpp с функциями по себе я получаю:

Undefined      first referenced 
symbol        in file 
main        /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crt1.o 
ld: fatal: Symbol referencing errors. No output written to a.out 
collect2: ld returned 1 exit status 

Вот функции, строки в настоящее время хэшированного в вектор списков:

template <class HashObj> 
bool HashTable<HashObj>::contains(HashObj &item) 
{ 
    const list<HashObj> & whichList = theLists[ myhash(item) ]; 
    return find(whichList.begin(), whichList.end(), item) != whichList.end();  
}   

template <class HashObj> 
bool HashTable<HashObj>::insert(const HashObj &item) 
{ 
    list<HashObj> & whichList = theLists[ myhash(item) ]; 
    if(find(whichList.begin(), whichList.end(), item) != whichList.end()) 
     return false; 
    whichList.push_back(item); 
    return true; 
} 

template <class HashObj> 
bool HashTable<HashObj>::remove(const HashObj &item) 
{ 
    list<HashObj> & whichList = theLists[ myhash(item) ]; 
    typename list<HashObj>::iterator itr = find(whichList.begin(), whichList.end(), item); 

    if(itr == whichList.end()) 
    return false; 

    whichList.erase(itr); 
    return true; 
} 

Это функция myhash из того же файла:

template <class HashObj> 
int HashTable<HashObj>::myhash(const HashObj &item) const 
{ 
    int hashVal = hash(item); 

    hashVal %= theLists.size(); 
    if (hashVal < 0) 
     hashVal += theLists.size(); 

    return hashVal; 
} 

Приведенный выше код .cpp имеет включают hashTable.h, который в свою очередь включает в себя hashPrototypes.h

В hashPrototypes .h is

int hash(int key); 
int hash(const string &key); 

и моя хэш-функция скомпилирована из файла makefile, который создает исполняемый файл на основе того, что y ou введите. Например, я использую hash1.cpp, поэтому, набрав make HASH = hash1, он должен скомпилировать их все вместе.

Вот мой hash1.cpp код:

#include "hashTable.h" 
#include <cmath> 
#include <cstdlib> 
using namespace std; 

template <class HashObj> 
int hash(const HashObj &item) 
    { 
    int hashVal = 0; 

    for(int i = 0; i < item.length(); i++) 
     hashVal = 37 * hashVal + item[ i ]; 

    return hashVal; 
} 

Если вы считаете, что ошибка в Makefile, вот код Makefile:

# Make file for hashing 
# Executable for the program will be in: hashTest 

#default function is looked for in hashS1 
#to give it another function make=filename without the suffix 
HASH = hashS1 

$(HASH)Test: $(HASH).o hashTable.o hashApp.o 
    g++ -o $(HASH)Test $(HASH).o hashTable.o hashApp.o 

hashApp.o:  hashTable.h hashPrototypes.h hashApp.cpp hashTable.cpp 
    g++ -c hashApp.cpp 

hashTable.o: hashTable.h hashTable.cpp $(HASH).cpp 
g++ -c hashTable.cpp 

$(HASH).o: hashPrototypes.h $(HASH).cpp 
g++ -c $(HASH).cpp 

clean: 
rm -f *.o 
touch * 
+0

Можете ли вы опубликовать код для функции 'myhash()'? Похоже, вы можете использовать 'std :: hash', в этом случае вам, вероятно, просто нужно« #include », но это трудно сделать. –

+0

', когда я пытаюсь скомпилировать .cpp-файл с помощью своих функций ...' Нет, это не актуально. – john

+0

У вас есть неопределенный символ 'hash', но ничто в коде, который вы опубликовали, не использует символ' hash'. Поэтому из опубликованного кода это немного загадка. Опубликуйте больше кода. – john

ответ

3

Проблема заключается в том, что вы поставили шаблон кода в файле cpp. All template code should go in header files. В противном случае вы получаете ошибки ссылок при использовании этих шаблонов.

+0

В программе был код шаблона, прежде чем добавить вставку, удалить и содержать функции (как, например, вышеупомянутая функция myhash), и она была скомпилирована. Может ли это быть проблемой? – Rekson

+0

Я не знаю о структуре остальной части вашего кода (это не совсем ясно из вашего вопроса), но у вас есть ошибка ссылки, у вас есть код шаблона в файле cpp, размещение кода шаблона в файле cpp - это хорошо известная причина ошибок связи (см. ссылку выше). Вы не должны помещать код шаблона в файл cpp. Исправьте это, и если у вас все еще есть проблемы, попросите еще раз. – john

+0

Иногда, чтобы обойти эту проблему, люди делают код шаблона в файле cpp, но затем #include cpp-файл в файле заголовка. Конечно, это то же самое, код шаблона эффективно находится в файле заголовка. Возможно, это то, что происходит с вашим другим кодом. – john

0

Нашел вопрос, это было проще, чем я думал, но ответ Джона относительно того, где код шаблона помог.

Оказывается, мне нужно было сделать свою функцию хеширования (а не myhash) не templated-классом и заставить ее взять строковую переменную. Это очевидно для меня сейчас, посмотрев на прототипе:

int hash(const string &key); 

я только предположил, что во время моего первоначального создания определения, что это было бы шаблонный класс, как и все остальное!

Смежные вопросы