私が抱えている問題は、作成したクラスのコンストラクターを呼び出すと、次のエラーが発生することです。
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"
誰でも説明してください:
なぜこれで問題が解決するのですか?
.hppファイルを含めることで、.cppが暗黙的に含まれないのはなぜですか?
これを行うより良い方法はありますか?
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ファイルを独自のオブジェクトとしてコンパイルし、2つのオブジェクトをリンクします。
NetBeansについてはあまり知りませんが、おそらくGameObject/StaticObject.cppはコンパイルするソースの一部として含まれていません。
そのため、main.cppに手動で含めると、ソースコードが見つかり、すべて問題ありません。
私は同じ問題を抱えていましたが、私はEclipse CDTをandAutotools projectで使用しているためでしたそのため、新しい.h
および.cpp
ファイルを対応するMakefile.am
に手動で追加してから、project> reconfigure project、rebuild、それ。