【发布时间】:2010-05-23 07:08:32
【问题描述】:
我有文件 Record.h 和 Record.cpp。当我只包含 Record.h 文件时,我会收到几个未定义的对这些文件中定义的函数的引用错误。当我还包括 Record.cpp 时,错误就会消失。这是为什么? Record.h 具有它所说的未定义引用的函数的前向声明。
记录.h
#ifndef RECORD_
#define RECORD_
#include <string>
#include <limits>
using namespace std;
#define PKEYSIZE 10
#define STREETNUMSIZE 8
#define STREETNAMESIZE 24
#define RNAMESIZE 30
#define ASTYLESIZE 20
#define YEARSIZE 12
#define MAXBUCKETSIZE 4
#define MAXDIRECTORYSIZE 100
typedef struct
{
char streetNum[STREETNUMSIZE];
char streetName[STREETNAMESIZE];
char rName[RNAMESIZE];
char aStyle[ASTYLESIZE];
char year[YEARSIZE];
char pkey[PKEYSIZE];
} RECORD;
typedef struct
{
int size;
int depth;
RECORD record[MAXBUCKETSIZE];
} BUCKET;
#define HEADERSIZE 2L
#define NODESIZE sizeof(BUCKET)
void addKey(RECORD *rec_ptr, string key);
void addStreetNum(RECORD *rec_ptr, string s);
void addStreetName(RECORD *rec_ptr, string s);
void addRName(RECORD *rec_ptr, string s);
void addAStyle(RECORD *rec_ptr, string s);
void addYear(RECORD *rec_ptr, string s);
void printRecord(RECORD *rec_ptr);
ostream & operator<<(ostream & out, RECORD *r);
string cvt_binary(unsigned int input);
void addRecord(RECORD *r);
void showbucket(int n);
#endif
记录.cpp
int dirDepth = 0;
int numberOfBuckets = 0;
int directory[MAXDIRECTORYSIZE];
BUCKET bucket[MAXDIRECTORYSIZE/MAXBUCKETSIZE];
void addKey(RECORD *rec_ptr, string key)
{
strncpy(rec_ptr->pkey, key.c_str(), PKEYSIZE);
}
void addStreetNum(RECORD *rec_ptr, string s)
{
strncpy(rec_ptr->streetNum, s.c_str(), STREETNUMSIZE);
}
void addStreetName(RECORD *rec_ptr, string s)
{
strncpy(rec_ptr->streetName, s.c_str(), STREETNAMESIZE);
}
void addRName(RECORD *rec_ptr, string s)
{
strncpy(rec_ptr->rName, s.c_str(), RNAMESIZE);
}
void addAStyle(RECORD *rec_ptr, string s)
{
strncpy(rec_ptr->aStyle, s.c_str(), ASTYLESIZE);
}
void addYear(RECORD *rec_ptr, string s)
{
strncpy(rec_ptr->year, s.c_str(), YEARSIZE);
}
void printRecord(RECORD *rec_ptr)
{
cout<< "|"
<< rec_ptr->pkey << "|"
<< rec_ptr->streetNum << "|"
<< rec_ptr->streetName << "|"
<< rec_ptr->rName << "|"
<< rec_ptr->aStyle << "|"
<< rec_ptr->year << endl;
}
ostream & operator<<(ostream & out, RECORD *r)
{
out << r->pkey << r->streetNum << r->streetName << r->rName
<< r->aStyle << r->year << endl;
return out;
}
int bucketread(short rrn, BUCKET *page_ptr)
{
// long lseek(), addr;
long addr;
addr = (long)rrn * (long)NODESIZE + HEADERSIZE;
lseek(btfd, addr, 0);
return ( read(btfd, page_ptr, NODESIZE) );
}
int bucketwrite(short rrn, BUCKET *page_ptr)
{
// long lseek(), addr;
long addr;
addr = (long) rrn * (long) NODESIZE + HEADERSIZE;
lseek(btfd, addr, 0);
return (write(btfd, page_ptr, NODESIZE));
}
void showbucket(int n)
{
cout << "loading bucket " << n << endl;
BUCKET b;
bucketread(n, &b);
cout << "there are " << b.size << " records in the bucket" << endl;
}
string cvt_binary(unsigned int input) {
if(input == 0) return "0"; // trivial case
string result;
for(int i = numeric_limits<unsigned int>::digits - 1; i >= 0; --i) {
if(input & (1 << i))
{
result += "1";
}
else
{
if(!result.empty()) result += "0";
}
}
return result;
}
string hash (char* key)
{
int sum = 0;
int len = strlen(key);
if (len % 2 == 1) len++; // make len even
//for an odd length string, use the trailing 0 as part of key
for (int j = 0; j < len; j +=2)
sum = (sum + 100 * key[j] + key[j+1]) % 19937;
return cvt_binary(sum);
}
void copyrecord(RECORD *dest, RECORD *src)
{
cout << "copying record" << endl;
addKey(dest, src->pkey);
addStreetNum(dest, src->streetNum);
addStreetName(dest, src->streetName);
addRName(dest, src->rName);
addAStyle(dest, src->aStyle);
addYear(dest, src->year);
}
void addToBucket(int n, RECORD *r)
{
cout << "Adding record " << r->pkey << " to bucket " << n << endl;
if (bucket[n].size == MAXBUCKETSIZE)
{
cout << "Bucket " << n << " is full." << endl;
// examine bucket depth and directory depth to determine next action
cout << "Bucket depth: " << bucket[n].depth << endl;
cout << "Directory depth: " << directory[0] << endl;
}
else
{
copyrecord(&bucket[n].record[bucket[n].size],r);
bucket[n].size++;
bucketwrite(1,&bucket[1]);
}
}
string getreverse(string key, int num)
{
if(num==0)
return "";
string newstring;
newstring = key.at(key.length());
newstring+= getreverse(key.substr(0,key.length()-1),num-1);
return newstring;
}
void addRecord(RECORD *r)
{
cout << r->pkey << endl;
string hashvalue = hash(r->pkey);
cout << "hash value is " << hashvalue << endl;
int directoryDepth = directory[0];
if(directoryDepth == 0)
{
directory[1] = 1;
addToBucket(1, r);
}
else
{
// use hashing to figure out which bucket to add to
cout << "The relevant string is" << getreverse(hashvalue, directoryDepth) << endl;
}
}
【问题讨论】:
-
我使用的是 g++,它通常可以正常工作。
-
请不要在头文件中使用
using namespace std;,只能在实现文件中使用。 -
即使在实现文件中,也最好只对你经常使用的符号进行,永远不需要带整个命名空间。
标签: c++ include linker header-files