我遇到的问题是,当我为我创建的类调用构造函数时,出现以下错误。
main.cpp:20:未定义的引用 `StaticObject::StaticObject(图形*, sf::字符串,
sf::Vector2)'
这个问题可以通过在 main.cpp 中添加 .cpp 文件来“修复”,就像这样。
...
#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;
...
静态对象.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;
};
静态对象.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"
谁能解释一下:
为什么这可以解决问题?
为什么.cpp没有通过包含.hpp而隐式包含 文件?
有更好的方法吗?
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
中,然后执行 project > 重新配置项目,重建,就是这样。
我在 Qt 中遇到了同样的问题,我忘记将类添加到 pro 文件中。显然,如果不将其添加到 pro 文件中,编译器将无法识别它。所以我添加了它,然后再次运行 qmake,这解决了问题。
基本上,您需要在源中添加文件。
我时常遇到这个问题。
根本原因与其他人已经说过的相同:您需要将库链接到可执行文件。
因此,要在 Netbeans 中使用静态库,您需要在项目属性下的许多位置引用该项目(对于每个配置):
Build/C++ Compiler
下搜索 Include directories
- 添加这些文件所在的目录。#include "../GameObject/StaticObject.hpp" // set include paths to get rid of ../GameObject/
Linker
搜索 Libraries
下 - 添加所有定义所在的静态库。这很重要,因为这可能会导致上述错误。Related Projects
下再次添加您的项目。