2013-10-08 29 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); 

我我最初創作的定義,它會像其他一切一個模板類的過程中只是假設!