[C++] Problem beim Kompilieren

f.reischl

Admiral Special
Mitglied seit
21.09.2002
Beiträge
1.394
Renomée
2
Beim kompilieren der einkauf.cpp bekomme ich folg. Fehlermeldung:
Code:
einkauf.cpp: undefined reference to `operator>>(std::istream&, Betrag&)'
einkauf.cpp: undefined reference to `operator>>(std::istream&, Mystring&)'
einkauf.cpp: undefined reference to `Mystring::operator==(Mystring const&) const'
einkauf.cpp: undefined reference to `operator>>(std::istream&, Betrag&)'
einkauf.cpp: undefined reference to `Betrag::operator+=(Betrag&)'
einkauf.cpp: undefined reference to `Betrag::operator+(Betrag const&)'
einkauf.cpp: undefined reference to `Betrag::operator<=(Betrag&) const'
einkauf.cpp: undefined reference to `Betrag::operator+(Betrag const&)'
einkauf.cpp: undefined reference to `Betrag::operator<=(Betrag&) const'
einkauf.cpp: undefined reference to `operator<<(std::ostream&, Mystring const&)'
einkauf.cpp: undefined reference to `Betrag::operator<=(Betrag&) const'
einkauf.cpp: undefined reference to `Mystring::~Mystring()'
einkauf.cpp: undefined reference to `Mystring::~Mystring()'
collect2: ld returned 1 exit status

Execution terminated

Mein Prof. hätte gemeint, er müsste funktionieren... :]

Hier noch der vollständige Quellcode:
Code:
/////////////////////////////////////////////////////
//                                                 //
// Deklaration der Klasse Mystring                 //
// Datei      mystring.h                           // 
// Datum      11.5.05                              //
//                                                 //
/////////////////////////////////////////////////////   

#ifndef MYSTRING_H
#define MYSTRING_H

#include<iostream>
#include<cstring>                // die klassischen C-Stringfunktionen
using namespace std;

class Mystring
{
public:
// Konstruktoren;
   Mystring():derstring(NULL){};    // Standardkonstruktor
   Mystring(char* inhalt);          // auch Typumwandlungskonstruktor!
   Mystring(const Mystring& s);     // Copy - Konstruktor
// Destruktor
   ~Mystring();      

// Operatoren und Zugriffsfunktionen  
   Mystring& operator=(const Mystring& s);
   bool operator>(const Mystring& s) const;      
   bool operator<(const Mystring& s) const;      
   bool operator==(const Mystring& s) const;
   bool operator!=(const Mystring& s) const;
   char* c_str() const {return derstring;}
   int size() const {return laenge;}
   char& operator[](int i){return derstring[i];}

// befreundete Funktionen   
   friend Mystring operator+(const Mystring& s, const Mystring& t);   
   friend ostream& operator<<(ostream& cout,const Mystring& s);
   friend istream& operator>>(istream& cin, Mystring& s);

private:
   int laenge;
   char* derstring;
};

#endif

/////////////////////////////////////////////////////
//                                                 //
// Implementierung der Klasse Mystring             //
// Datei      mystring.cpp                         // 
// Datum      11.5.05                              //
//                                                 //
/////////////////////////////////////////////////////  

#include "mystring.h"    

// members
Mystring::Mystring(char* inhalt)
{
   laenge = strlen(inhalt);
   derstring = new char[laenge+1];   
   strcpy(derstring,inhalt);
}

Mystring::Mystring(const Mystring& s)    // Copy Konstruktor
{
   laenge = s.laenge;
   derstring = new char[laenge+1]; // vorheriges delete ist nicht n”tig  
   strcpy(derstring,s.derstring);  // da bei Kopie das Objekt neu erzeugt 
}                                  // wird (es ist sogar falsch!)
   
Mystring::~Mystring()              // Destruktor - wird immer nach Ende der
{                                  // Lebensdauer aufgerufen. "delete" darf
   if (derstring != NULL)          // nur ausgefhrt werden, wenn vorher
      delete[] derstring;          // mit "new" Speicher reserviert wurde!
}      

Mystring& Mystring::operator=(const Mystring& s)   // Zuweisungsoperator
{                                   
   laenge = s.laenge;
   if(this == &s)                  // noetig z.B. fuer eine Zuweisung s = s.
      return *this;                // Dann darf kein delete gemacht werden!
   if (derstring != NULL)          // Wenn schon mal new gemacht wurde, 
      delete []derstring;          // dann alten Speicherplatz l”schen    
   derstring = new char[laenge+1]; // und neuen Speicherplatz reservieren 
   strcpy(derstring,s.derstring);
   return *this;
}

bool Mystring::operator>(const Mystring& s) const     
{
   if(strcmp(derstring,s.derstring)>0)
      return true;
   else
      return false;    
}
                                            
bool Mystring::operator<(const Mystring& s) const     
{
   if(strcmp(derstring,s.derstring)<0)
      return true;
   else
      return false;    
}                                            

bool Mystring::operator==(const Mystring& s) const     // Vergleichsoperator
{
   return !strcmp(derstring,s.derstring);    // !strcmp() ist "true" falls
}                                            // die strings gleich sind
                                            
bool Mystring::operator!=(const Mystring& s) const
{
   return strcmp(derstring,s.derstring);     
}                                           

// friends

ostream& operator<<(ostream& cout ,const Mystring& s)  // Bildschirmausgabe
{
   cout << s.derstring;
   return cout;
}

istream& operator>>(istream& cin, Mystring& s)         // Tastatureingabe
{  
   char eingabe[256];
   
   cin >> eingabe;
   s.laenge = strlen(eingabe);
   if (s.derstring != NULL)          
      delete[] s.derstring;
   s.derstring = new char[s.laenge+1]; 
   strcpy(s.derstring,eingabe);  
   return cin;
}

Mystring operator+(const Mystring& s, const Mystring& t)   // Additionsoperator
{                                   
   Mystring summe;
   summe.laenge = s.laenge + t.laenge;
   summe.derstring = new char[summe.laenge+1];   
   strcpy(summe.derstring,s.derstring);
   strcat(summe.derstring,t.derstring);
   return summe;
}

/////////////////////////////////////////////////////
//                                                 //
// Deklaration der Klasse Betrag                   //
// Datei      Betrag.h                             // 
// Datum      11.5.05                              //
//                                                 //
/////////////////////////////////////////////////////  

#ifndef BETRAG_H
#define BETRAG_H

#include <iostream>            
using namespace std;

class Betrag
{
public: 

// Konstruktoren
   Betrag():eu(0),ce(0){}            		 // Standardkonstruktor
   Betrag(int e, int c):eu(e+c/100),ce(c%100){}  // Initialisierungsliste 
   Betrag(int c):eu(c/100),ce(c%100){}           
   
// Zugriffsfunktionen
   int euro() const{return eu;}     
   int cent() const{return ce;}                
   
// Operatoren
   Betrag & operator+=(Betrag& q);
   bool operator<=(Betrag& q) const;   
   bool operator==(Betrag& q) const;   
   Betrag operator+(const Betrag& q);
   
// befreundete Funktionen
   friend ostream& operator<<(ostream& cout,const Betrag& p);
   friend istream& operator>>(istream& cin ,Betrag& p);
private:
   int eu;
   int ce;
};

#endif
/////////////////////////////////////////////////////
//                                                 //
// Implementierung der Klasse Betrag               //
// Datei      betrag.cpp                           // 
// Datum      11.5.05                              //
//                                                 //
/////////////////////////////////////////////////////  

#include "betrag.h"

// members 
Betrag& Betrag::operator+=(Betrag& q) 
{
   eu += q.eu + (ce + q.ce)/100;
   ce = (ce + q.ce)%100;
   return *this;
}

bool Betrag::operator<=(Betrag& q) const
{
   if(eu < q.eu)
      return true;    
   if(eu == q.eu && ce <= q.ce)
      return true;
   else
      return false;
}

bool Betrag::operator==(Betrag& q) const
{
   if(eu == q.eu && ce == q.ce)
      return true;
   else
      return false;
}

Betrag Betrag::operator+(const Betrag& q)
{
   Betrag s;
   
   s.eu = eu + q.eu +(ce+q.ce)/100;
   s.ce = (ce+q.ce)%100;
   return s;
}

// friends
ostream& operator<<(ostream& cout ,const Betrag& p)
{
   cout << p.eu << ',';
   cout.fill('0');
   cout.width(2);
   cout << p.ce;
   return cout;
}

istream& operator>>(istream& cin ,Betrag& pr)
{  
   int e, c;
   cin >> e;
   cin >> c;
   pr = Betrag(e,c);
   return cin;
}

/////////////////////////////////////////////////////
//                                                 //
// Anwendungsbeispiel fuer Mystring und Betrag     //
// Datei      einkauf.cpp                          // 
// Datum      11.5.05                              //
//                                                 //
/////////////////////////////////////////////////////  

#include <iostream>
#include "betrag.h"
#include "mystring.h" 

using namespace std;

int main()
{  

   Betrag summe, geld, einzelpreis; 
   const Betrag eincent = 1;               
          
   cout << "Wieviel Geld haben Sie dabei?" << endl;
   cin >> geld;                              // ueberladenes ">>" fuer Betrag
   
   Mystring artikel[5];                      // 5 x Standardkonstruktor
   int i=0;
   
   do
   {
      cout << "Was wollen Sie einkaufen?" << endl;
      cin >> artikel[i++];                   // ueberladenes ">>" fuer Mystring
      if(i>1 && artikel[i-1]==artikel[i-2])  // ueberladenes "==" fuer Mystring
      {
         cout << "Das haben Sie doch gerade erst gekauft!" << endl;
         i--;
      }
      else
      {              
         cout << "Was kostet das?" << endl;
         cin >> einzelpreis;                
         summe += einzelpreis;               // ueberladenes "+=" fuer Betrag
         if(geld + eincent <= summe)         // "+" und "<=" sind fuer Betrag
         {                                   // ueberladen (nicht "<", darum  
            cout << "zu teuer! ";            // der eine Cent)
            i--;
         } 
      }
   }while(i < 5 && (summe + eincent <= geld));  // d.h. summe < geld!
   
   cout << "Sie haben " << endl << endl;
   for(int j=0; j < i; j++)
      cout << '\t' << artikel[j] << endl;
   cout << "\neingekauft. ";
   if (geld <= summe)
      cout << "Jetzt ist das Geld alle." << endl;
   else 
      cout << "Mehr gibt's nicht!" << endl;      
}  

/* Programmablauf:

Wieviel Geld haben Sie dabei?               
10 0                                        
Was wollen Sie einkaufen?                   
Kaese                                       
Was kostet das?                             
4 32                                        
Was wollen Sie einkaufen?                   
Kaese                                       
Das haben Sie doch gerade erst gekauft!     
Was wollen Sie einkaufen?                   
Brot                                        
Was kostet das?                             
3 50                                        
Was wollen Sie einkaufen?                   
Wein                                        
Was kostet das?                             
8 80                                        
zu teuer! Sie haben                         
                                           
        Kaese                               
        Brot                                
                                           
eingekauft. Jetzt ist das Geld alle.        */

Verwendet wird Dev-Cpp v4.9.9.2 mit Mingw/GCC v3.4.2
 
versuch doch mal, die einzelnen dateien getrennt zu kompilieren und am ende zusammen zu binden... so in etwa:
Code:
fabian@madhouse ~/test $ g++ -c mystring.cpp; g++ -c betrag.cpp; g++ -c einkauf.cpp
fabian@madhouse ~/test $ g++ -o einkauf mystring.o betrag.o einkauf.o
hat zumindest bei mir einwandfrei funktioniert (unter gentoo linux, gcc 3.4.4)
Code:
fabian@madhouse ~/test $ ls
betrag.cpp  betrag.h  betrag.o  einkauf  einkauf.cpp  einkauf.o  mystring.cpp  mystring.h  mystring.o
 
Stimmt, jetzt gehts auch bei mir...
Ich sollte dann doch mal ein Makefile hernehmen...
Vielen Dank.
 
Zurück
Oben Unten