30

私が抱えている問題は、作成したクラスのコンストラクターを呼び出すと、次のエラーが発生することです。

main.cpp:20: 「StaticObject::StaticObject(Graphics*, sf::String,
sf::Vector2)」への未定義の参照

この問題は、main.cpp に .cpp ファイルのインクルードを追加することで「修正」できます。

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

これで問題は解決しますが、これは不十分な解決策のように思われ、以前に言われたことに反します。この問題を解決する他の方法はありますか? このプログラムをコーディング/コンパイルするために、g ++でNetbeans 7.3を使用しています。以下は関連するコードです。

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. これを行うより良い方法はありますか?

4

6 に答える 6

23

このundefined referenceエラーは、関数/メソッド (ここではコンストラクター) の定義がリンカーによって見つからなかったことを示しています。

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

そして、次の行を追加する理由:

#include "GameObject/StaticObject.cpp"

問題を修正しmain.cppます。実際の実装はの一部として実装されますStaticObject.cpp。これは、この問題を修正するための間違った方法です。

私は Netbeans をあまり使用していませんが、Netbeans がすべての.oファイルを単一の実行可能ファイルにリンクするように、すべての .cpp ファイルを単一のプロジェクトに追加するオプションがあるはずです。

StaticObject.cppが独自のライブラリに組み込まれている場合 (ここではそうではないかと思います)、リンカーが実装を見つけられるように、このライブラリの場所へのパスを指定する必要がある場合があります。

これは、プログラムをビルドするときに理想的に起こることです:

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

gcc/g++ には、すべての中間 .o ファイル生成をスキップして .o ファイルを直接生成する方法がありますmain_programが、同じコマンド ラインですべてのソース ファイル (および任意のライブラリ) を指定する場合。

于 2013-03-22T20:26:45.330 に答える
9

リンカは の定義を見つけることができませんStaticObject。これは、StaticObject.cpp をコンパイルおよびリンクしていないことを意味します。各 .cpp ファイルは個別にコンパイルする必要があり、コンパイラが各ファイルに対して生成するオブジェクト ファイルをリンカーに渡す必要があります。

Main.cpp に StaticObject.cpp を含める理由は、コンパイル中の Main.cpp に StaticObject.cpp の内容を挿入するようにプリプロセッサに指示しているためです。そのため、定義は Main.cpp のコンパイル済み出力の一部になります。

于 2013-03-22T20:26:22.413 に答える
4

cpp ファイルをインクルードすると、コンパイラはそのコードをそのファイルの一部としてビルドします (これは行うべきではありません)。必要なことは、GameObject/StaticObject.cpp ファイルを独自のオブジェクトとしてコンパイルし、2 つのオブジェクトをリンクすることです。

于 2013-03-22T20:31:18.543 に答える
2

私はネットビーンズのことをあまり知りませんが、おそらく GameObject/StaticObject.cpp はコンパイルするソースの一部として含まれていません。

そのため、main.cpp に手動でインクルードすると、ソース コードが見つかり、すべて問題ありません。

于 2013-03-22T20:27:54.917 に答える
1

私は同じ問題を抱えていましたが、私は Eclipse CDT とAutotools projectを使用しているためです。.hそのため、新しいと.cppファイルを対応するに手動で追加してからMakefile.amproject > reconfigure project、rebuild を実行する必要がありました。

于 2016-01-05T00:28:31.697 に答える