Anfängerfrage [Linker error] undefined reference to



  • Hallo zusammen,

    ich versuche mich derzeit an einem kleinem Spiel.
    Ich bekomme folgenden Fehler, welchen ich nicht verstehe:

    [Linker error] undefined reference to `Zufall::Zufall()'
    

    Den gleichen Fehler hatte ich, als ich verstucht habe in meiner main eine Zufallszahl zu generieren. Dort musste ich vor die main Funktion die Konstruktoren und des Destruktor von Zufall.h schreiben, warum?
    Jetzt habe ich dort (siehe unten) Konstruktor und Destruktor von Monster.h, verstehe aber immer noch nicht, warum er das von mir verlangt.

    Zufall.h

    #ifndef ZUFALL_H
    #define ZUFALL_H
    
    class Zufall
    {
      public:                          
        Zufall();                      // der Default-Konstruktor
        Zufall(int zufallszahl);       // weiterer Konstruktor mit Parameter
        ~Zufall();                     // der Destruktor
    
        int ZufallsZahl(int max);       
    
    };
    #endif // ZUFALL_H
    

    Zufall.cpp

    #include "Zufall.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int Zufall::ZufallsZahl(int max){
        int i;
        time_t t;
        int result;
    
        time(&t);
        srand((unsigned int)t);              /* Zufallsgenerator initialisieren */
        result = rand() % max;
    
        return result;
        }
    

    Monster.h

    #ifndef MONSTER_H
    #define MONSTER_H
    #include <string>
    #include "Zufall.h"
    
    class Monster
    {
      public:                          
        Monster();                      // der Default-Konstruktor
        Monster(int zufallszahl);       // weiterer Konstruktor mit Parameter
        ~Monster();                     // der Destruktor
    
        std::string monsterName;
        int monsterStrength;
        int monsterIntellegence;
        int monsterHP;
        int monsterMP;
        int monsterStamina;
    
        void createMonster();
    
    };
    #endif
    

    Monster.cpp

    #include "Monster.h"
    #include "Zufall.h"
    #include <string>
    #include <cstdlib>
    #include <iostream>
    
    void Monster::createMonster() {
         Zufall zufall;
         std::string monsterName0 = "T-Rex";
         std::string monsterName1 = "Dilo";
         std::string monsterName2 = "Raptor";
         std::string monsterName3 = "Carno";
         std::string monsterName4 = "Argentavis";
         std::string monsterName5 = "Trike";
         std::string monsterName = "Namenloses Monster";
    
         std::cout << "Beginne Erstellung von Monster. Random Nr. wird generiert." << std::endl;
         int zufallszahl;
         zufallszahl = zufall.ZufallsZahl(6);
    
        }
    

    Game.cpp (main)

    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <iostream>
    #include "Monster.h"
    
    Monster::Monster(){}
    Monster::~Monster(){}
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        Monster monster;
    
        monster.createMonster();
    
    [...]
    

    Kann mir jemand weiterhelfen?
    Ich habe ebenfalls versucht die Konstruktoren in Monster.h vor den Beginn der Klasse zu schreiben.



  • Wo ist denn Dein Constructor Zufall() ?

    ich seh ihn nicht

    mfg Martin



  • Guck dir die Meldung doch mal an. Der Linker kann ein bestimmtes Symbol nicht finden, nämlich...?
    Btw sind Init-Methoden doof, dein Zufallsgenerator wird bei jeder Zahl neu initialisiert und außerdem gibts wchon einen in <random>



  • mgaeckler schrieb:

    Wo ist denn Dein Constructor Zufall() ?

    ich seh ihn nicht

    mfg Martin

    Der befindet sich in Zufall.h

    #ifndef ZUFALL_H
    #define ZUFALL_H
    
    class Zufall
    {
      public:                          
        Zufall();                      // der Default-Konstruktor
        Zufall(int zufallszahl);       // weiterer Konstruktor mit Parameter 
        ~Zufall();                     // der Destruktor
    
        int ZufallsZahl(int max);       
    
    };
    #endif // ZUFALL_H
    

    roflo schrieb:

    Guck dir die Meldung doch mal an. Der Linker kann ein bestimmtes Symbol nicht finden, nämlich...?
    Btw sind Init-Methoden doof, dein Zufallsgenerator wird bei jeder Zahl neu initialisiert und außerdem gibts wchon einen in <random>

    Wo gibt es was in <random>? Und warum ist das doof?



  • Es geht plötzlich doch.
    Meine erste Änderung, nach welcher ich den selben Fehler bekommen habe war in Monster.h Konstruktor und Destruktor wieder anzulegen:

    #ifndef MONSTER_H
    #define MONSTER_H
    #include <string>
    #include "Zufall.h"
    
    Zufall::Zufall(int max){}
    Zufall::Zufall(){}
    Zufall::~Zufall(){}
    
    class Monster
    {
      public:                          
        Monster();                      // der Default-Konstruktor
        Monster(int zufallszahl);       // weiterer Konstruktor mit Parameter
        ~Monster();                     // der Destruktor
    
        std::string monsterName;
        int monsterStrength;
        int monsterIntellegence;
        int monsterHP;
        int monsterMP;
        int monsterStamina;
    
        void createMonster();
    
    };
    #endif
    

    Bis zu diesem Punkt funktionierte es wie gesagt nicht, ich habe das Projekt nach der ersten Änderung komplett neu erstellt ("alles neu erstellen"). Kein Erfolg.
    Ich verstehe auch immer noch nicht, warum dies helfen soll, ich bin lediglich bei der Fehlersuche auf diese Lösung gestoßen.

    Meine Zweite Änderung war etwas was überhaupt nicht damit zu tun hat in Monster.cpp

    #include "Monster.h"
    #include "Zufall.h"
    #include <string>
    #include <cstdlib>
    #include <iostream>
    
    void Monster::createMonster() {
         Zufall zufall;
         std::string monsterName0 = "T-Rex";
         std::string monsterName1 = "Dilo";
         std::string monsterName2 = "Raptor";
         std::string monsterName3 = "Carno";
         std::string monsterName4 = "Argentavis";
         std::string monsterName5 = "Trike";
         //std::string monsterName = "Namenloses Monster";
    
         std::cout << "Beginne Erstellung von Monster. Random Nr. wird generiert." << std::endl;
         int zufallszahl;
         zufallszahl = zufall.ZufallsZahl(6);
         std::cout << zufallszahl << std::endl;
    
         if (zufallszahl == 0) {
              monsterName = monsterName0;
              }
         else if (zufallszahl == 1) {
              monsterName = monsterName1;
              }
         else if (zufallszahl == 2) {
              monsterName = monsterName2;
              }
         else if (zufallszahl == 3) {
              monsterName = monsterName3;
              }
         else if (zufallszahl == 4) {
              monsterName = monsterName4;
              }     
         else if (zufallszahl == 5) {
              monsterName = monsterName5;
              }
         else {
              std::cout << "Da ist was schief gelaufen, es konnte kein Monster erstellt werden!\nIst die Zufallszahl richtig? " << zufallszahl << std::endl;
              }
         std::cout << "Es ist ein " << monsterName << std::endl;
    
        }
    

    Jetzt funktioniert es.



  • Erstelle jetzt mal einfach so eine neue klasse spieler mit entsprechender Header-und Quelldatei, welche wiederum Monster inkludiert.



  • Wenn du in der Header Datei und in der Definition deiner Klasse verschiedene Konstruktoren und einen Destruktor deklarierst muss dieser auch irgendwo definiert werden. Nochmal mit Codebeispielen. Dies ist die Deklaration deines Konstruktors:

    class Zufall
    {
    public:
      Zufall();  // Deklaration
      // ...
    }
    

    Gleichzeitig brauchst du aber auch eine Definition:

    Zufall::Zufall(){}
    

    Üblicherweise schreibt man die Definition in die dazugehörige *.cpp Datei und nicht in eine völlig andere. Die Definition des Zufall Konstruktors gehört also in die Zufall.cpp und die Definition des Monster Konstruktors in die Monster.cpp, nicht in die Game.cpp oder sowas.



  • sebi707 schrieb:

    Wenn du in der Header Datei und in der Definition deiner Klasse verschiedene Konstruktoren und einen Destruktor deklarierst muss dieser auch irgendwo definiert werden. Nochmal mit Codebeispielen. Dies ist die Deklaration deines Konstruktors:

    class Zufall
    {
    public:
      Zufall();  // Deklaration
      // ...
    }
    

    Gleichzeitig brauchst du aber auch eine Definition:

    Zufall::Zufall(){}
    

    Üblicherweise schreibt man die Definition in die dazugehörige *.cpp Datei und nicht in eine völlig andere. Die Definition des Zufall Konstruktors gehört also in die Zufall.cpp und die Definition des Monster Konstruktors in die Monster.cpp, nicht in die Game.cpp oder sowas.

    Danke dir vielmals 👍 Da lag mein Fehler 🙂
    Habe es nun behoben und es funktioniert alles einwandfrei 🙂


Anmelden zum Antworten