web-dev-qa-db-ja.com

.cppファイルの修正を含む、クラスコンストラクターへの未定義の参照

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

main.cpp:20: `StaticObject :: StaticObject(Graphics *、sf :: String、への未定義の参照
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;
...

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

22
OMGtechy

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を直接生成する方法がありますが、同じコマンドラインですべてのソースファイル(およびライブラリ)を指定する場合。

19
Tuxdude

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

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

6
JBentley

cppファイルを含めると、コンパイラはそのコードをそのファイルの一部としてビルドします(実行しないでください)。必要なのは、GameObject/StaticObject.cppファイルを独自のオブジェクトとしてコンパイルし、2つのオブジェクトをリンクします。

3
bizzehdee

NetBeansについてはあまり知りませんが、おそらくGameObject/StaticObject.cppはコンパイルするソースの一部として含まれていません。

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

2
padilo

私は同じ問題を抱えていましたが、私はEclipse CDTをandAutotools projectで使用しているためでしたそのため、新しい.hおよび.cppファイルを対応するMakefile.amに手動で追加してから、project> reconfigure project、rebuild、それ。

0
jotadepicas