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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15579172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:30:24  来源:igfitidea点击:

Undefined reference to class constructor, including .cpp file fixes

c++debuggingnetbeansg++

提问by OMGtechy

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: undefined reference to `StaticObject::StaticObject(Graphics*, sf::String,
sf::Vector2)'

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

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

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

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

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.

尽管这解决了问题,但这似乎是一个糟糕的解决方案,并且与我之前被告知的情况背道而驰。有没有其他方法可以解决这个问题?我正在使用 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

静态对象.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

静态对象.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() {
}

If I add the following line to main.cpp, the error disappears.

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

#include "GameObject/StaticObject.cpp"

Can anyone please explain:

谁能解释一下:

  1. Why this fixes the problem?

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

  3. Is there a better way of doing this?

  1. 为什么这可以解决问题?

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

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

采纳答案by Tuxdude

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

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

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

And the reason that adding the following line:

以及添加以下行的原因:

#include "GameObject/StaticObject.cpp"

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

修复的问题,是在实施带来的的一部分main.cpp,而你的实际执行中StaticObject.cpp。这是解决此问题的不正确方法

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 .ofiles into a single executable.

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

If StaticObject.cppis 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.

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

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

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.

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

回答by JBentley

The linker cannot find the definition for StaticObject, which means you have not compiled and linked StaticObject.cpp. Each .cpp file needs to be separately compiled, and the object files the compiler produces for each one needs to be given to the linker.

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

The reason including StaticObject.cpp in Main.cpp works is that you are telling the preprocessor to insert the contents of StaticObject.cpp into Main.cpp, which you are compiling, so the definitions become part of Main.cpp's compiled output.

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

回答by bizzehdee

including the cpp file causes the compiler to build that code as part of that file (which you should not do), what you need to do is compile the GameObject/StaticObject.cpp file as its own object, and link the 2 objects together.

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

回答by padilo

I dont know much of netbeans, but probably GameObject/StaticObject.cpp is not included as part of the sources to compile.

我对 netbeans 了解不多,但可能 GameObject/StaticObject.cpp 没有包含在要编译的源代码中。

That's why if you include it manually at main.cpp he found source code and everything is ok.

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

回答by jotadepicas

I had the same issue but mine was because I'm using Eclipse CDT with and Autotools project. So I had to manually add the new .hand .cppfiles to the corresponding Makefile.am, and then do a project > reconfigure project, rebuild, an that was it.

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