Problem mit "Medienverwaltung" C++ 

Status
Für weitere Antworten geschlossen.

kunks

Registered +
Registriert
Dez. 2003
Beiträge
326
Hey FSB'ler,

hab mal wieder n kleines Problem. Diesmal mit C++..
Und zwar müssen wir im OOP Kurs eine kleine "Medienverwaltung" schreiben. Bin eigentlich ganz zufrieden, bis auf die Tatsache dass ich, seitdem ich den Code in drei verschiedenen Dateien (header.h für Klassendefinitionen, main.cpp: Hauptprogramm, classfunc.cpp: Klassen)
immer Fehler beim Compilieren bekomme :rolleyes:

Hier die Fehlermeldung(en):
Code:
nic@nic-laptop:~/Dokumente/Studium/2.Semester/OOP/übung2$ g++ -o ausgabe main.cpp classfunc.cpp
/tmp/ccx7maTO.o: In function `Buch::Buch()':
classfunc.cpp:(.text+0x476): undefined reference to `Medium::Medium(int)'
/tmp/ccx7maTO.o: In function `Buch::Buch()':
classfunc.cpp:(.text+0x58c): undefined reference to `Medium::Medium(int)'
/tmp/ccx7maTO.o: In function `Video::Video()':
classfunc.cpp:(.text+0x6a2): undefined reference to `Medium::Medium(int)'
/tmp/ccx7maTO.o: In function `Video::Video()':
classfunc.cpp:(.text+0x7b8): undefined reference to `Medium::Medium(int)'
collect2: ld gab 1 als Ende-Status zurück
nic@nic-laptop:~/Dokumente/Studium/2.Semester/OOP/übung2$

Hier der/die Code(s):
PHP:
//Headerdatei (header.h)

#ifndef HEADER_H
#define HEADER_H
#include 
#include 
#include 
#include 
using namespace std;

class Medium {
public:
Medium();
Medium(int);
int getsignatur();
void print();
void entleihen();
void rueckgabe();
protected:
int signatur;
string titel;
string typ;
bool status;
};

class Buch : public Medium {
public:
Buch();
void print();
void entleihen();
void rueckgabe();
private:
int seiten;
};

class Video : public Medium {
public:
Video();
void print();
void entleihen();
void rueckgabe();
private:
float spieldauer;
}; 
#endif

//main.cpp

#include "header.h"


const int S = 20;


int main(){

const int N = 10;
char eingabe;
Medium* neuM[N]; 
int m = 0, v = 0, b = 0;
Video* neuV[N] = {NULL};
Buch* neuB[N] = {NULL}; 
int sig_check;

while(1){
cout  cout  Anlegen und Initialisieren"  cout  Hinzufügen und Initialisieren eines neuen Buches"  cout  Hinzufügen und Initialisieren eines neuen Videos"  cout  Anzeige der Medieneigenschaft"  cout  Ausleihen"  cout  Rückgabe"  cout  Programmende"  cout  cin >> eingabe;
cout  
switch(eingabe){
case 'm': //if(neu == NULL)
//delete neu;
if (m >= N)
cout  else{ 
neuM[m] = new Medium;
m++;
} 
break;

case 'b': if (b >= N)
cout  else{ 
neuB[b] = new Buch;
b++;
} 
break;

case 'v': if (v >= N)
cout  else{ 
neuV[v] = new Video;
v++;
}
break;

case 'l': cout  cout  for (int i = 0; i < m; i++){ 
neuM[i]->print();
cout  }
for (int i = 0; i < b; i++){
neuB[i]->print();
cout  }
for (int i = 0; i < v; i++){
neuV[i]->print();
cout  }
break;

case 'e': cout  cin >> sig_check;
for(int i = 0; i  if (neuM[i]->getsignatur() == sig_check)
neuM[i]->entleihen();
}
for(int i = 0; i  if (neuB[i]->getsignatur() == sig_check)
neuB[i]->entleihen();
} 
for(int i = 0; i  if (neuV[i]->getsignatur() == sig_check) 
neuV[i]->entleihen();
} 
break;

case 'r': cout  cin >> sig_check;
for(int i = 0; i  if (neuM[i]->getsignatur() == sig_check)
neuM[i]->rueckgabe();
}
for(int i = 0; i  if (neuB[i]->getsignatur() == sig_check)
neuB[i]->rueckgabe();
} 
for(int i = 0; i  if (neuV[i]->getsignatur() == sig_check) 
neuV[i]->rueckgabe();
} 
break;

case 'q': return 0;
break;

}
} 

return 0;
}

//classfunc.cpp

#include "header.h"

const int S = 20;

Medium::Medium(){

status = false;
cout   cin >> signatur;
cin.ignore(10,'\n');
cout  getline(cin, titel);
typ.assign("Medium");
}

void Medium::print(){
cout  }
int Medium::getsignatur(){
return signatur;
}
void Medium::entleihen(){
if(status == true){
status = false;
cout  }
}
void Medium::rueckgabe(){
if(status == false){
status = true;
cout  }

}





Video::Video():Medium(0) {

status = false;
cout   cin >> signatur;
cin.ignore(10,'\n');
cout  getline(cin, titel);
cout  cin >> spieldauer;
typ.assign("Video");
}


void Video::print(){
Medium::print();
cout  }
void Video::entleihen(){
Medium::entleihen();
}

void Video::rueckgabe(){
Medium::rueckgabe(); 
}


Buch::Buch():Medium(0) {

status = false;
cout   cin >> signatur;
cin.ignore(10,'\n');
cout  getline(cin, titel);
cout  cin >> seiten;
typ.assign("Buch");
}
void Buch::print(){
Medium::print();
cout  }
void Buch::entleihen(){
Medium::entleihen();
}
void Buch::rueckgabe(){
Medium::rueckgabe();
}

Kann mir vielleicht jemand weiter helfen? Komm nicht drauf was der Compiler von mir will bzw. warum er meckert. Compiler is C++

MfG kunks
 
Also so wie ich das sehe hast du den Medium(int) Konstruktor zwar deklariert, aber nicht definiert, in deiner classfunc.cpp sollte folgendes stehen:
Code:
Medium::Medium(int i){
//irgendwas
}
 
Der Medium(int) Konstruktor soll nur ein Dummy sein. Da steht also nichts drin. Aber ich werds mal testen, vllt. klappts ja ;)
 
Beim Anlegen eines Mediums werden weniger Angaben als beim Anlegen eines Buches bzw. Videos. die Konstruktoren meiner Klasse und die der Unterklassen sind verschieden. Deshalb brauch ich einen Dummykonstruktor, damit in den Unterklassen nicht der Defaultkonstruktor mit den falschen Werten aufgerufen wird..
 
Dann wäre sowas denk ich eleganter:

PHP:
Medium::Medium(BOOL subclass = false) {
if(!subclass) {
// mache das was medium machen soll
} else { // *edit: Wenn wirklich nichts gemacht werden soll kann das else natürlich gelöscht werden
// mache nichts
}
}

so kannst du den konstruktor für ein medium mit default aufrufen: Medium bla = new Medium();

und in der subklasse z.B. im Buch konstruktor: Buch::Buch():Medium(true) { /*...*/ }

P.S. Alles ungetestet ;) Man möge Schreibfehler entschuldigen
 
Wieso machst Du denn die Eingabe im Konstruktor ???
IMHO sollten im Konstruktor nur allgemeine Initialisierungen stattfinden.
Spendiere doch den Klassen einfach noch die Methoden
Medium::eingabe (), Video ::eingabe () und Buch :: eingabe ()
Dann brauchst Du auch den Dummy Konstruktor nicht mehr.
 
Also erstmal :thx: für die vielen guten Antworten. Das mit der fehlenden Definition war natürlich richtig, daran lag es dass das Programm erst gar nicht kompiliert werden konnte.

Jo stimmt, Eingabe im Konstruktor ist nicht so praktisch, sollen wir aber so machen :rolleyes:
Naja, ich weiß jetzt nicht ob ihr mich richtig verstanden habt, wegen dem Dummy Konstruktor. Der hat halt nur die Funktion, das beim Anlegen eines neuen Buches bzw. Videos, nicht der gleiche Text wie beim Medium kommt, also statt "Bitte Mediendaten eingeben.." soll, beispielsweise beim Buch, "Bitte Buchdaten eingeben.." angezeigt werden. Unser Tutor hat dann gemeint ich könnt son Dummy machen und den halt leer lassen, das nicht der Default-Konstruktor aufgerufen wird...

Hab jetzt no n Problem mit der entleihen() bzw. rueckgabe() Methode.
Kompilieren geht, nur kommt, wenn die beiden Methoden augerufen werden und ich was eintippe immer "segmentation fault core dump" und mein Programm bricht ab :(

Was kann das sein?
 
kunks schrieb:
Hab jetzt no n Problem mit der entleihen() bzw. rueckgabe() Methode.
Kompilieren geht, nur kommt, wenn die beiden Methoden augerufen werden und ich was eintippe immer "segmentation fault core dump" und mein Programm bricht ab :(

Was kann das sein?
Vermutlich hast du zu wenig Speicher für die Eingabe allokiert. Normal kommt so ein Fehler vor wenn du versuchst mehr Daten in eine Variable zu speichern als du im Speicher vorgesehen hast.
 
Also die Eingabe is korrekt, es wird genug Speicher allokiert. Bin echt am Ende mit meinen Ideen.. Bekomm immer "Segmentation fault"

Kann sich das vllt. jemand kurz anschaun, ob die Methode "rueckgabe" bzw. das Kommando "r" wenigstens vom Prinzip funktionieren müsste.

PHP:
//Kommando "r" in main.cpp
case 'r': cout  cin.ignore(100, '\n');
cin >> sig_check;
//cout  for(int i = 0; i  if (neuM[i]->getsignatur() == sig_check)
neuM[i]->rueckgabe();
}
for(int i = 0; i  if (neuB[i]->getsignatur() == sig_check)
neuB[i]->rueckgabe();
} 
for(int i = 0; i  if (neuV[i]->getsignatur() == sig_check) 
neuV[i]->rueckgabe();
} 
break;

//rueckgabe Methode
void Medium::rueckgabe(){
if(status == false){
status = true;
cout  }else cout  
}

//die getsignatur Methode 
int Medium::getsignatur(){
return signatur;

Wäre euch sehr dankbar ;)

MfG kunks
 
gut ja bin nich so erfahren in cpp aber:
PHP:
int Medium::getsignatur(){
return signatur; 
// es fehlt ne klammer:
}
sonst funzt glaub alles
 
Oh, die habe ich hier im Beitrag vergessen :rolleyes:
In meinem Programm ist die schon drin, sonst hätte der Compiler ja gemeckert ;) Hat er aber nicht...

Bin mit meinem Latein echt am Ende, weiß nicht was ich da machen kann :confused:

MfG kunks
 
Nochmal den completten code posten, der ganz oben ist sicher nicht mehr aktuell oder? Würd dir gern helfen wenn ich kann :)
 
Also, ich sehe es auch so wie janine.

Du hast den Konstruktor und den Dummy-Konstruktor im Header definiert.
Also Medium (); und Medium (int);

Aber in classfunc.cpp gibt es keine Implementierung des Dummy-Konstruktors, sondern nur den Standard-Konstruktors:
Medium::Medium()
{ ... }
Es fehlt aber
Medium::Medium (int i)
{ ... }

Daher kommt dann auch die Fehlermeldung, da die abgeleiteten Klassen Buch und Video auf den Dummy-Konstruktor zugreifen wollen.
 
habs jetzt soweit hinbekommen.. Habe aber bestimmt wieder Fragen, da das Programm die Daten statt in einem array in einer verketteten liste speichern soll. Daran arbeite ich gerade ;)

melde mich dann wieder

MfG kunks
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben Unten