c++ - C++ 中 undefined reference 错误

标签 c++ include linker header-files

我有文件 Record.h 和 Record.cpp。当我只包含 Record.h 文件时,我收到了一些对这些文件中定义的函数的 undefined reference 错误。当我还包含 Record.cpp 时,错误就会消失。这是为什么? Record.h 具有其所说的 undefined reference 的函数的前向声明。

记录.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;

    }

}

最佳答案

Record.h 具有这些函数的声明。 Record.cpp 具有定义

//Record.h

void foo(); // This is a forward declaration

到目前为止一切顺利。

//main.cpp

#include "Record.h"

int main()
{
    foo();
}

现在 main.o 可以正常编译了。但是,如果您尝试将其链接到工作二进制文件,您会收到一条错误消息,指出 void foo() 未定义。

//Record.cpp

#include "Record.h"

// This is the definition
void foo()
{
    // do various things
}

它可以被编译成 Record.o,然后可以与 main.o 链接成一个工作可执行文件。

关于c++ - C++ 中 undefined reference 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2890916/

相关文章:

c++ - C++中的 "a<?=b"是什么意思?

c++ - 围绕点的二维旋转

include - Sequelize : Scope with where condition not working with singular and plural

c++ - Premake OpenGL SDK 无法从教程构建项目

c++ - GCC 使用旧版本的 C++

c++ - 这个带有指针函数的 strcpy 有什么问题?

c++ - Keil uVision4 armcc : Using C++ standard includes <cstdint>

php - 使用 PHP include 时改变 CSS sprite 导航栏的状态

c - 如何将 'link' 目标文件转换为可执行/编译的二进制文件?

windows - GHC::在 Windows 上再次链接 sqlite3 失败