2013-10-08 25 views
0

我有一组文件可以用makefile编译来创建单独的哈希程序。 该程序的功能,直到我添加代码插入,删除,并包含功能。我直接从书中提取代码,但是我得到了一个模糊的错误,我无法弄清楚,希望有人能够帮助识别它。因为我是在一个受过教育的猜测错误的原因不会在外部的代码中找到我没有张贴整个程序(但我可能是错的)C++哈希程序中未定义的符号错误

有问题的错误是:

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是

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

我的散列函数从一个makefile中编译,该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,这里是生成文件代码:

# 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

你有一个未定义的符号“哈希”,但是你发布的代码中没有使用称为“哈希”的符号。所以从发布的代码来看,这有点神秘。发布更多代码。 – 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)成为一个非模板类,并使其成为一个字符串变量。这是明显,我看后的原型现在:

int hash(const string &key); 

我我最初创作的定义,它会像其他一切一个模板类的过程中只是假设!