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

Undefined reference to class constructor, including .cpp file fixes

本文关键字:包括 cpp 文件修复 引用 未定义 构造函数      更新时间:2023-10-16

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

main.cpp:20:未定义的引用"StaticObject:: StaticObject(图形*,科幻小说:字符串,
科幻::Vector2) '

这个问题可以"修复",在main.cpp中添加。cpp文件的include,如下所示。

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

虽然这解决了问题,但这似乎是一个糟糕的解决方案,与我之前被告知的相反。还有其他方法可以解决这个问题吗?我使用Netbeans 7.3和g++来编码/编译这个程序。以下是相关代码:

main.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));
...

main.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. 为什么这个解决了问题?

  2. 为什么没有通过包含。hpp隐含地包含。cpp文件吗?

  3. 有更好的方法吗?

undefined reference错误表明链接器没有找到函数/方法的定义(即这里的构造函数)。

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

以及添加以下行的原因:

#include "GameObject/StaticObject.cpp"

修复了这个问题,它是作为main.cpp的一部分带来的实现,而你的实际实现是在StaticObject.cpp中。这是一个不正确的方法来解决这个问题。

我没有使用Netbeans太多,但应该有一个选项,以添加所有的。cpp文件到一个单一的项目,使Netbeans负责链接所有的.o文件到一个单一的可执行文件。

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

当你构建你的程序时,理想情况是这样的:

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

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

链接器找不到StaticObject的定义,这意味着您没有编译和链接StaticObject.cpp。每个.cpp文件需要单独编译,并且编译器为每个文件生成的目标文件需要提供给链接器。

在Main.cpp中包含StaticObject.cpp的原因是您告诉预处理器将StaticObject.cpp的内容插入到您正在编译的Main.cpp中,因此这些定义成为Main.cpp编译输出的一部分。

包含cpp文件会导致编译器将该代码构建为该文件的一部分(这是你不应该做的),你需要做的是将GameObject/StaticObject.cpp文件编译为自己的对象,并将这两个对象链接在一起。

我不太了解netbeans,但可能GameObject/StaticObject.cpp不包括在编译源的一部分。

这就是为什么如果你在main.cpp中手动包含它,他会找到源代码,一切正常

我有同样的问题,但我的问题是因为我使用Eclipse CDT和Autotools项目。所以我不得不手动添加新的.h.cpp文件到相应的Makefile.am,然后做一个项目>重新配置项目,重建,就是这样。

我在Qt中有同样的问题,我忘记将类添加到配置文件中。显然,如果不将其添加到配置文件中,编译器就无法识别它。所以我把它加进去,然后再次运行qmake,这就解决了问题。

基本上,您需要在源代码中添加文件。