Linker Error bei Implementierung einer Headerdatei



  • EDIT: Sorry, irgendwie funzen bei mir die Tags nicht, ich habe sowohl "Code" und "cpp" als auch "quote" probiert, aber die gehen beide nicht. 😞

    EDIT II: Seltsam im zweiten Beitrag gehen die Tags. Also der saubere Code steht dort, sorry für das Durcheinander, wäre schön, wenn ein Mod da mal draufschauen könnte, warum das beim ersten Beitrag mit den Tags nicht geht, danke schon einmal.

    Ich versuche mir gerade in Programm zu schreiben und arbeite dabei auch mit einer Klasse. Es geht darum Rechnungen mit mehreren himmelskörpern durchzuführen und diese will ich als Klasse vorher definieren. Die Klasse verfügt über verschiedene Attribute (Masse, Perizentrumsgeschwindigkeit, Perizentrumsposition) und diese können wiederum über einfache Textdateien abgespeichert, bzw. eingegeben werden.

    Es gibt nun folgenden code

    Die Headerdatei der Klasse grav_object

    // Header für grav_object
    #ifndef _GRAV_OBJECT_H_
    #define _GRAV_OBJECT_H_
    
    class grav_object
    
    {
    
          public:
    
                 grav_object(); 				//Constructors
                 ~grav_object(); 				//Destructor
    
                 double objectmass; 			//mass of the body
                 double Rp;         			// pericentre radius (assuming that the pericentre is on the x-axis)
                 double Vp;         			// pericentre velocity (see above)
    
                 double get_objectmass(int massnumber); 	//accessing the body's mass
                 double get_Rp(int massnumber); 		//accessing the body's pericentre radius
                 double get_Vp(int massnumber); 		//accessing the body's pericentre velocity
    
    };
    #endif
    

    Die CPP Datei der Klasse (die Funktionen sind identisch und fragen nur verschiedene Werte ab, sie funktionieren wie gewünscht, das habe ich in einer seperaten datei getestet):

    // Implementierung grav_object
    
    #include "grav_object.h"
    #include "stdlib.h" 
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    
          grav_object::grav_object()                            //Konstruktor
          {
                                     Rp = 0;
                                     Vp = 0;
                                     objectmass =0;
          }
    
          grav_object::~grav_object()                           // Destruktor
          {
          }
    
          double grav_object::get_objectmass(int massnumber)
          {
                 bool error = false;
                 string mass = "0";                         
                 //with massnumber the filename is created     
                 string filename("0");
                 int name_length = 0;
    
                 ostringstream outStream;
                 outStream << massnumber;
                 filename = outStream.str();
    
                 filename.insert(0, "mass");              //the name is added the addition "mass"
                 name_length = filename.length();         // reads the length of the string
                 filename.insert(name_length, ".dat");  // the filename is completed to massx.dat where x is the content of massnumber
    
                 //aus der Datei die Position der Masse finden, Masse auslesen (if-Abfrage)
    
                 ifstream file_in;
                 file_in.open(filename.c_str(), ios::in);       // .c_str() nicht vergessen, sonst funktioniert die Abfrage nicht!
    
                 do
                 {
                    file_in >> mass;
                          if (mass=="mass" || mass == "Mass")                  // the file is searched for an entry of the mass
                          {
                             file_in >> mass;                              // if so the value behind mass is input into the string mass
                             error = false;
                          }
                          else 
                          {
                               error = true;                               // if no value is found, error is set to true
                          };
    
                 }while(!file_in.eof());
    
                 if (error == true)       
                 {cout << "No mass has been found, please make sure your input is given as 'mass x' where x is the correct value" << endl;
                      };                                                   // error message that no mass has been given
    
                 istringstream inStream(mass);
                 inStream >> objectmass;
    
                 return objectmass;
    
                 }
    
          double grav_object::get_Rp(int massnumber)
          {
                 bool error = false;
                 string radius = "0";                         
                 //with massnumber the filename is created     
                 string filename("0");
                 int name_length = 0;
    
                 ostringstream outStream;
                 outStream << massnumber;
                 filename = outStream.str();
    
                 filename.insert(0, "mass");              //the name is added the addition "mass"
                 name_length = filename.length();         // reads the length of the string
                 filename.insert(name_length, ".dat");  // the filename is completed to massx.dat where x is the content of massnumber
    
                 //aus der Datei die Position der Masse finden, Masse auslesen (if-Abfrage)
    
                 ifstream file_in;
                 file_in.open(filename.c_str(), ios::in);       // .c_str() nicht vergessen, sonst funktioniert die Abfrage nicht!
    
                 do
                 {
                    file_in >> radius;
                          if (radius=="Rp" || radius == "rp")                  // the file is searched for an entry of the mass
                          {
                             file_in >> radius;                              // if so the value behind mass is input into the string mass
                             error = false;
                          }
                          else 
                          {
                               error = true;                               // if no value is found, error is set to true
                          };
    
                 }while(!file_in.eof());
    
                 if (error == true)       
                 {cout << "No radius has been found, please make sure your input is given as 'radius x' where x is the correct value" << endl;
                      };                                                   // error message that no mass has been given
    
                 istringstream inStream(radius);
                 inStream >> Rp;
    
                 return Rp;
    
                 }
    
          double grav_object::get_Vp(int massnumber)
                 {
                 bool error = false;
                 string velocity = "0";                         
                 //with massnumber the filename is created     
                 string filename("0");
                 int name_length = 0;
    
                 ostringstream outStream;
                 outStream << massnumber;
                 filename = outStream.str();
    
                 filename.insert(0, "mass");              //the name is added the addition "mass"
                 name_length = filename.length();         // reads the length of the string
                 filename.insert(name_length, ".dat");  // the filename is completed to massx.dat where x is the content of massnumber
    
                 //aus der Datei die Position der Masse finden, Masse auslesen (if-Abfrage)
    
                 ifstream file_in;
                 file_in.open(filename.c_str(), ios::in);       // .c_str() nicht vergessen, sonst funktioniert die Abfrage nicht!
    
                 do
                 {
                    file_in >> velocity;
                          if (velocity=="Vp" || velocity == "vp")                  // the file is searched for an entry of the mass
                          {
                             file_in >> velocity;                              // if so the value behind mass is input into the string mass
                             error = false;
                          }
                          else 
                          {
                               error = true;                               // if no value is found, error is set to true
                          };
    
                 }while(!file_in.eof());
    
                 if (error == true)       
                 {cout << "No velocity has been found, please make sure your input is given as 'velocity x' where x is the correct value" << endl;
                      };                                                   // error message that no mass has been given
    
                 istringstream inStream(velocity);
                 inStream >> Vp;
    
                 return Rp;
    
    }
    

    Und jetzt die Quelldatei des Hauptprogramms:

    #include "grav_object.h"
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <cmath>
    #include <stdlib.h> 
    
    using namespace std;
    
    int main()
    {
        grav_object planet;    
        double masse = 0;  
    
        masse = planet.get_objectmass(1);        
        cout << masse << endl;
    
        cout << "Zum Beenden"<< endl;
        system("PAUSE");
    
     return 0;   
    }
    

    Ich bekomme folgenden Fehler:

    [Linker error] undefined reference to grav\_object::grav\_object()' [Linker error] undefined reference tograv_object::get_objectmass(int)'
    [Linker error] undefined reference to grav\_object::~grav\_object()' [Linker error] undefined reference tograv_object::~grav_object()'
    ld returned 1 exit status

    Interessant dabei ist imho, dass ich den Fehler des Destruktors zwei mal bekomme. Ich dachte auch erst, dass der Grund ist, dass die Headerdatei nicht gefunden wird, dies ist aber nicht das Problem, denn ich habe einfach mal den Namen verändert und bekam dann den Fehler, dass die Datei unbekannt ist.
    Ich habe auch ausprobiert einfach einen falschen Funktionsnamen zu verwenden, bei richtiger Headerdatei, auch da bekam ich den Fehler, dass die Funktion nicht existiert... Sprich, die Headerdatei wird gefunden und auch richtig gelesen.
    Wenn ich statt der Headerdatei die cpp-Datei include funktioniert das ganze, wäre ja aber nicht im Sinne des Erfinders. Ich hoffe es kann mir jemand helfen.

    Ich benutze Dev-C++ Bloodshed und habe Windows Vista 32 bit SP2.
    Danke schon einmal für die mögliche Unterstützung.



  • Header Datei:

    // Header für grav_object
    #ifndef _GRAV_OBJECT_H_
    #define _GRAV_OBJECT_H_
    
    class grav_object
    
    {
    
          public:
    
                 grav_object(); 				//Constructors
                 ~grav_object(); 				//Destructor
    
                 double objectmass; 			//mass of the body
                 double Rp;         			// pericentre radius (assuming that the pericentre is on the x-axis)
                 double Vp;         			// pericentre velocity (see above)
    
                 double get_objectmass(int massnumber); 	//accessing the body's mass
                 double get_Rp(int massnumber); 		//accessing the body's pericentre radius
                 double get_Vp(int massnumber); 		//accessing the body's pericentre velocity
    
    };
    #endif
    

    Quelldatei für grav_object

    // Implementierung grav_object
    
    #include "grav_object.h"
    #include "stdlib.h" 
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    
          grav_object::grav_object()                            //Konstruktor
          {
                                     Rp = 0;
                                     Vp = 0;
                                     objectmass =0;
          }
    
          grav_object::~grav_object()                           // Destruktor
          {
          }
    
          double grav_object::get_objectmass(int massnumber)
          {
                 bool error = false;
                 string mass = "0";                         
                 //with massnumber the filename is created     
                 string filename("0");
                 int name_length = 0;
    
                 ostringstream outStream;
                 outStream << massnumber;
                 filename = outStream.str();
    
                 filename.insert(0, "mass");              //the name is added the addition "mass"
                 name_length = filename.length();         // reads the length of the string
                 filename.insert(name_length, ".dat");  // the filename is completed to massx.dat where x is the content of massnumber
    
                 //aus der Datei die Position der Masse finden, Masse auslesen (if-Abfrage)
    
                 ifstream file_in;
                 file_in.open(filename.c_str(), ios::in);       // .c_str() nicht vergessen, sonst funktioniert die Abfrage nicht!
    
                 do
                 {
                    file_in >> mass;
                          if (mass=="mass" || mass == "Mass")                  // the file is searched for an entry of the mass
                          {
                             file_in >> mass;                              // if so the value behind mass is input into the string mass
                             error = false;
                          }
                          else 
                          {
                               error = true;                               // if no value is found, error is set to true
                          };
    
                 }while(!file_in.eof());
    
                 if (error == true)       
                 {cout << "No mass has been found, please make sure your input is given as 'mass x' where x is the correct value" << endl;
                      };                                                   // error message that no mass has been given
    
                 istringstream inStream(mass);
                 inStream >> objectmass;
    
                 return objectmass;
    
                 }
    
          double grav_object::get_Rp(int massnumber)
          {
                 bool error = false;
                 string radius = "0";                         
                 //with massnumber the filename is created     
                 string filename("0");
                 int name_length = 0;
    
                 ostringstream outStream;
                 outStream << massnumber;
                 filename = outStream.str();
    
                 filename.insert(0, "mass");              //the name is added the addition "mass"
                 name_length = filename.length();         // reads the length of the string
                 filename.insert(name_length, ".dat");  // the filename is completed to massx.dat where x is the content of massnumber
    
                 //aus der Datei die Position der Masse finden, Masse auslesen (if-Abfrage)
    
                 ifstream file_in;
                 file_in.open(filename.c_str(), ios::in);       // .c_str() nicht vergessen, sonst funktioniert die Abfrage nicht!
    
                 do
                 {
                    file_in >> radius;
                          if (radius=="Rp" || radius == "rp")                  // the file is searched for an entry of the mass
                          {
                             file_in >> radius;                              // if so the value behind mass is input into the string mass
                             error = false;
                          }
                          else 
                          {
                               error = true;                               // if no value is found, error is set to true
                          };
    
                 }while(!file_in.eof());
    
                 if (error == true)       
                 {cout << "No radius has been found, please make sure your input is given as 'radius x' where x is the correct value" << endl;
                      };                                                   // error message that no mass has been given
    
                 istringstream inStream(radius);
                 inStream >> Rp;
    
                 return Rp;
    
                 }
    
          double grav_object::get_Vp(int massnumber)
                 {
                 bool error = false;
                 string velocity = "0";                         
                 //with massnumber the filename is created     
                 string filename("0");
                 int name_length = 0;
    
                 ostringstream outStream;
                 outStream << massnumber;
                 filename = outStream.str();
    
                 filename.insert(0, "mass");              //the name is added the addition "mass"
                 name_length = filename.length();         // reads the length of the string
                 filename.insert(name_length, ".dat");  // the filename is completed to massx.dat where x is the content of massnumber
    
                 //aus der Datei die Position der Masse finden, Masse auslesen (if-Abfrage)
    
                 ifstream file_in;
                 file_in.open(filename.c_str(), ios::in);       // .c_str() nicht vergessen, sonst funktioniert die Abfrage nicht!
    
                 do
                 {
                    file_in >> velocity;
                          if (velocity=="Vp" || velocity == "vp")                  // the file is searched for an entry of the mass
                          {
                             file_in >> velocity;                              // if so the value behind mass is input into the string mass
                             error = false;
                          }
                          else 
                          {
                               error = true;                               // if no value is found, error is set to true
                          };
    
                 }while(!file_in.eof());
    
                 if (error == true)       
                 {cout << "No velocity has been found, please make sure your input is given as 'velocity x' where x is the correct value" << endl;
                      };                                                   // error message that no mass has been given
    
                 istringstream inStream(velocity);
                 inStream >> Vp;
    
                 return Rp;
    
    }
    
    #include "grav_object.h"
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <cmath>
    #include <stdlib.h> 
    
    using namespace std;
    
    int main()
    {
        grav_object planet;    
        double masse = 0;  
    
        masse = planet.get_objectmass(1);        
        cout << masse << endl;
    
        cout << "Zum Beenden"<< endl;
        system("PAUSE");
    
     return 0;   
    }
    

    Die Fehlermeldung:

    [Linker error] undefined reference to `grav_object::grav_object()' 
      [Linker error] undefined reference to `grav_object::get_objectmass(int)' 
      [Linker error] undefined reference to `grav_object::~grav_object()' 
      [Linker error] undefined reference to `grav_object::~grav_object()' 
      ld returned 1 exit status
    

  • Mod

    Du gibst offensichtlich den aus der Quelldatei für grav_object erzeugten Objektcode nicht beim Linken des aus der main erzeugten Codes an. Wie das geht, findest du in der Doku deines Linkers/Compilers. Oder wenn jemand der sich mit dev C++ auskennt dies liest, kann er es dir auch sagen.



  • Zudem solltest du von DevC++ lieber zu einer aktuellen C++ IDE wechseln (z.B. Code::Blocks oder Visual C++ Express 2008)


Anmelden zum Antworten