1. ホーム
  2. c++

[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む

2022-01-26 06:56:15

質問

作成したクラスのコンストラクタを呼び出すと、次のようなエラーが発生します。

main.cpp:20: undefined reference to `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. もっと良い方法はないでしょうか?

どのように解決するのですか?

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

undefined reference

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

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

はこの問題を解決するために、その実装を #include "GameObject/StaticObject.cpp" にあるのに対して、実際の実装は main.cpp. これは 不正確な方法 をクリックすると、この問題を解決することができます。

Netbeansをあまり使ったことがないのですが、すべての.cppファイルを単一のプロジェクトに追加するオプションがあるはずです。 StaticObject.cpp ファイルを1つの実行ファイルにすることができます。

もし .o がそれ自身のライブラリに組み込まれている場合(ここではそうでないことを強く疑います)、リンカーが実装を見つけられるように、そのライブラリの場所へのパスを指定しなければならないかもしれません。

プログラムをビルドするときは、こうするのが理想的です。

StaticObject.cpp

gcc/g++ では、中間的な .o ファイルの生成をすべてスキップして、直接、.o ファイルを生成する方法があります。 Compile: StaticObject.cpp -> StaticObject.o Compile: main.cpp -> main.o Link: StaticObject.o, main.o -> main_program すべてのソースファイル(およびライブラリ)を同じコマンドラインで指定した場合。