对类构造函数的未定义引用,包括 .cpp 文件修复

2021-12-26 00:00:00 debugging g++ netbeans c++

我遇到的问题是,当我为我创建的类调用构造函数时,出现以下错误.

The problem I am having is that, when I call a constructor for a class I have created I get the following error.

main.cpp:20: 未定义的引用`StaticObject::StaticObject(Graphics*, sf::String,
SF::Vector2)'

main.cpp:20: undefined reference to `StaticObject::StaticObject(Graphics*, sf::String,
sf::Vector2)'

这个问题可以通过像这样在 main.cpp 中为 .cpp 文件添加一个包含来修复".

This problem can be 'fixed' adding an include for the .cpp file in main.cpp like so.

...
#include "GameObjects/StaticObject.cpp"
...

虽然这解决了问题,但这似乎是一个糟糕的解决方案,并且与我之前被告知的情况背道而驰.有没有其他方法可以解决这个问题?我正在使用 Netbeans 7.3 和 g++ 来编码/编译这个程序.下面是相关代码.

Although this solves the problem, this seems like a poor solution and goes against what I have been previously told. Is there any other way to solve this problem? I'm using Netbeans 7.3 with g++ to code/compile this program. Below is the relevant code.

ma??in.cpp

...

#include <SFML/Graphics.hpp>
#include "Graphics/Graphics.hpp"
#include "GameObjects/StaticObject.hpp"

int main(int argc, char** argv) {

    //SETUP
    Graphics graphics;

    background = new StaticObject(&graphics, "Data/Images/BackgroundPlaceholder.png",  sf::Vector2f(0,0));

...

ma??in.hpp

...

#include <SFML/Graphics.hpp>
#include "GameObjects/StaticObject.hpp"

...

// Objects
StaticObject *background;
...

StaticObject.hpp

#include <SFML/Graphics.hpp>
#include "../Graphics/Graphics.hpp"

class StaticObject{
public:
    StaticObject();
    StaticObject(Graphics *_graphics, sf::String texture_filename, sf::Vector2f _position);
    StaticObject(const StaticObject& orig);
    virtual ~StaticObject();
private:
    // The sprite stores the position
    sf::Sprite *sprite;
    sf::Texture *texture;
};

StaticObject.cpp

#include "StaticObject.hpp"
#include <SFML/Graphics.hpp>
#include "../Graphics/Graphics.hpp"

StaticObject::StaticObject(){    
}

StaticObject::StaticObject(Graphics *_graphics, sf::String texture_filename, sf::Vector2f _position) {
    sprite = _graphics->AddSprite(texture_filename);
    sprite->setPosition(_position);
}

StaticObject::StaticObject(const StaticObject& orig) {
}

StaticObject::~StaticObject() {
}

如果我将以下行添加到 main.cpp,错误就会消失.

#include "GameObject/StaticObject.cpp"

谁能解释一下:

  1. 为什么这能解决问题?

  1. Why this fixes the problem?

为什么没有通过包含 .hpp 隐式包含 .cpp文件?

Why the .cpp was not implicitly included through including the .hpp file?

有没有更好的方法来做到这一点?

Is there a better way of doing this?

推荐答案

undefined reference 错误表示链接器未找到函数/方法(即此处的构造函数)的定义.

The undefined reference error indicates that the definition of a function/method (i.e constructor here) was not found by the linker.

StaticObject::StaticObject(Graphics*, sf::String,    sf::Vector2<float>)

以及添加以下行的原因:

And the reason that adding the following line:

#include "GameObject/StaticObject.cpp"

解决了这个问题,它是否将实现作为 main.cpp 的一部分引入,而您的实际实现是在 StaticObject.cpp 中.这是解决此问题的错误方法.

fixes the issue, is it brings in the implementation as part of the main.cpp whereas your actual implementation is in StaticObject.cpp. This is an incorrect way to fix this problem.

我没有经常使用 Netbeans,但是应该有一个选项可以将所有 .cpp 文件添加到单个项目中,以便 Netbeans 负责将所有 .o 文件链接到一个单个可执行文件.

I haven't used Netbeans much, but there should be an option to add all the .cpp files into a single project, so that Netbeans takes care of linking all the .o files into a single executable.

如果 StaticObject.cpp 内置到它自己的库中(我非常怀疑这里的情况),那么您可能必须指定该库位置的路径,以便链接器可以找到实现.

If StaticObject.cpp is built into a library of its own (I highly doubt that is the case here), then you might have to specify the path to the location of this library, so that the linker can find the implementation.

当您构建程序时,理想情况下会发生这种情况:

This is what ideally happens when you build your program:

Compile: StaticObject.cpp -> StaticObject.o
Compile: main.cpp -> main.o
Link: StaticObject.o, main.o -> main_program

尽管在 gcc/g++ 中有一些方法可以跳过所有中间 .o 文件生成并直接生成 main_program,如果您在同一命令行中指定所有源文件(和任何库).

Although there are ways in gcc/g++ to skip all the intermediate .o file generations and directly generate the main_program, if you specify all the source files (and any libraries) in the same command line.

相关文章