G++ - 对已定义成员函数的未定义引用

G++ - Undefined Reference to member function that is defined

本文关键字:函数 未定义 引用 成员 定义 G++      更新时间:2023-10-16

我目前正在开发一个处于非常早期阶段的虚拟运行时环境程序,由于使用我的makefile时出现链接器错误,我无法继续我的工作,如下所示。我收到的错误是:

g++ controller.o processor.o test.o -o final
controller.o: In function `Controller::run()':
controller.cpp:(.text+0x1e0): undefined reference to
Processor::codeParams(char)'
controller.o: In function `Controller::fetch()':
controller.cpp:(.text+0x290): undefined reference to `Controller::pc'
controller.cpp:(.text+0x299): undefined reference to `Controller::pc'
collect2: error: ld returned 1 exit status
makefile:16: recipe for target 'final' failed
make: *** [final] Error 1

我不确定为什么会出现此错误,因为我认为我已经在与标头对应的源文件中定义了这些内容。所有文件将在下面给出,以便可以编译程序。

测试.cpp:

#include <iostream>
#include <vector>
#include "includes/controller.h"
using namespace std;
int main()
{
    vector<char> prog = {0x0};
    Controller contr(prog);
    cout << "Error Code: " << contr.run() << endl;
    return 0;
}

控制器.cpp:

/*
    Author(s):  James Dolan
    File:       controller.cpp
    Build:      0.0.0
    Header:     includes/controller.h
    DoLR:       21:39 11/1/2017
    Todo: n/a
*/

#include "includes/controller.h"

Controller::Controller(vector<char> prog)
{
    printf("Program:");                         //Display program
    for(auto i : program)
    {
        printf("%02X", i);
    }
    printf("n");
    Controller::program = program;
}
Controller::~Controller ()
{
}
int Controller::run()
{
    bool runFlag = true;
    int errorCode = 0;
    char curCode;
    vector<char> curInstr;
    int paramRef;
    while(runFlag)
    {
        curCode = fetch();
        printf("curCode:%02Xn", curCode);
        curInstr.push_back(curCode);
        paramRef = proc.codeParams(curCode);
        if (paramRef == 0xffff){runFlag = false; continue;}     //Check if shutdown signal was returned, if so shutdown
        printf("opcode goodn");
        for(int i; i<paramRef; i++){curInstr.push_back(fetch());}
    }

    return errorCode;
}
char Controller::fetch()
{
    return program[pc++];                       //Return next instruction then increment the program counter
}

控制器.h:

/*
    Author(s):  James Dolan
    File:       controller.h
    Source:     ../controller.cpp
    DoLR:       21:39 11/1/2017
    Todo: n/a
*/

#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <iostream>
#include <vector>
#include <cstdlib>
#include "processor.h"
using namespace std;
class Controller{
    public:
        Controller(vector<char> prog);
        ~Controller();
        int run();
    protected:
    private:
        vector<char> program;
        static int pc;
        char fetch();
        Processor proc();

};
#endif

处理器.cpp:

#include "includes/processor.h"
Processor::Processor()
{
}
Processor::~Processor()
{
}
int codeParams(char code)
{
    switch(code)
    {
        case 0x0:                   //Halt
            return 0;
        default:
            printf("[ERROR!] Invalid opcode [%02X]", code);
            return 0xffff;          //Return shutdown signal
    }
}

处理器.h:

#ifndef PROCESSOR_H
#define PROCESSOR_H
#include <iostream>
#include <cstdlib>
class Processor{
    public:
        Processor();
        ~Processor();
        int codeParams(char code);
    protected:
    private:
};
#endif
非常感谢任何帮助,

因为它将帮助我继续开发像java vm这样的成熟的开源虚拟运行时环境的热情,感谢您的时间。

在控制器中.cpp您需要一个int Controller::pc;int Controller::pc = 0;

在头文件中,您声明了一个名为 pc 的静态 int,该 int 存在于某处。它需要实际存在于某个翻译单元中的某个地方(在本例中为 Controller.cpp),以便当链接器尝试查找它时......它存在。

在处理器中.cpp您的签名应该看起来像int Processor::codeParams(char code),让编译器知道这是处理器的 codeParams,而不是一个名为 codeParams 的随机函数,该函数恰好也采用一个字符。

对于成员函数Processor::codeParams,应将其定义为:

int Processor::codeParams(char code)
//  ~~~~~~~~~~~
{
  ...
}

否则,它只是一个普通的(非成员)函数。

对于静态成员Controller::pc您应该在类定义之外的 controller.cpp 中定义它。

// Controller.h
class Controller {
    ...
    private:
        static int pc;
};
// controller.cpp
int Controller::pc;