web-dev-qa-db-fra.com

Référence non définie au constructeur de classe, y compris les correctifs de fichiers .cpp

Le problème que j'ai est que, lorsque j'appelle un constructeur pour une classe que j'ai créée, j'obtiens l'erreur suivante.

main.cpp: 20: référence non définie à `StaticObject :: StaticObject (Graphics *, sf :: String,
sf :: Vector2) "

Ce problème peut être "corrigé" en ajoutant une inclusion pour le fichier .cpp dans main.cpp comme ceci.

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

Bien que cela résout le problème, cela semble être une mauvaise solution et va à l'encontre de ce qui m'a été dit précédemment. Existe-t-il un autre moyen de résoudre ce problème? J'utilise Netbeans 7.3 avec g ++ pour coder/compiler ce programme. Ci-dessous le code correspondant.

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() {
}

Si j'ajoute la ligne suivante à main.cpp, l'erreur disparaît.

#include "GameObject/StaticObject.cpp"

Quelqu'un peut-il expliquer:

  1. Pourquoi cela résout le problème?

  2. Pourquoi le .cpp n'a pas été implicitement inclus en incluant le fichier .hpp?

  3. Existe-t-il une meilleure façon de le faire?

22
OMGtechy

Le undefined reference erreur indique que la définition d'une fonction/méthode (c'est-à-dire le constructeur ici) n'a pas été trouvée par l'éditeur de liens.

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

Et la raison pour laquelle l'ajout de la ligne suivante:

#include "GameObject/StaticObject.cpp"

résout le problème, est-ce qu'il apporte l'implémentation dans le cadre du main.cpp alors que votre implémentation réelle est en StaticObject.cpp. Il s'agit d'une ( manière incorrecte pour résoudre ce problème.

Je n'ai pas beaucoup utilisé Netbeans, mais il devrait y avoir une option pour ajouter tous les fichiers .cpp dans un seul projet, afin que Netbeans se charge de lier tous les .o fichiers en un seul exécutable.

Si StaticObject.cpp est intégré à sa propre bibliothèque (je doute fort que ce soit le cas ici), vous devrez peut-être spécifier le chemin d'accès à l'emplacement de cette bibliothèque, afin que l'éditeur de liens puisse trouver l'implémentation.

Voici ce qui se passe idéalement lorsque vous créez votre programme:

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

Bien qu'il existe des moyens dans gcc/g ++ pour ignorer toutes les générations de fichiers .o intermédiaires et générer directement le main_program, si vous spécifiez tous les fichiers source (et toutes les bibliothèques) dans la même ligne de commande.

19
Tuxdude

L'éditeur de liens ne peut pas trouver la définition de StaticObject, ce qui signifie que vous n'avez pas compilé et lié StaticObject.cpp. Chaque fichier .cpp doit être compilé séparément et les fichiers objets que le compilateur produit pour chacun doivent être fournis à l'éditeur de liens.

La raison pour laquelle StaticObject.cpp fonctionne dans Main.cpp fonctionne est que vous dites au préprocesseur d'insérer le contenu de StaticObject.cpp dans Main.cpp, que vous compilez, de sorte que les définitions deviennent une partie de la sortie compilée de Main.cpp.

6
JBentley

y compris le fichier cpp oblige le compilateur à construire ce code dans le cadre de ce fichier (ce que vous ne devriez pas faire), ce que vous devez faire est de compiler le fichier GameObject/StaticObject.cpp comme son propre objet et de lier les 2 objets ensemble.

3
bizzehdee

Je ne connais pas beaucoup les netbeans, mais probablement GameObject/StaticObject.cpp n'est pas inclus dans les sources à compiler.

C'est pourquoi si vous l'incluez manuellement sur main.cpp, il a trouvé le code source et tout va bien.

2
padilo

J'ai eu le même problème mais le mien était parce que j'utilise Eclipse CDT avec et le projet Autotools . J'ai donc dû ajouter manuellement les nouveaux fichiers .h Et .cpp Aux Makefile.am Correspondants, puis faire projet> projet de reconfiguration, reconstruire, et c'était tout.

0
jotadepicas