Hausaufgabe finde den Fehler nicht
-
Hallo,
ich bin dabei meine Hausaufgabe zu schreiben. Ein Program, welches zwei beliebig lange strings addiert.
Bsp.: oiif und asd werden zu oiifasdden Code den ich bisher habe sieht so aus:
#include <iostream> #include <string> #include "zeichenkette.h" #include <cstring> using namespace std; int main() { ClZeichenkette zk1, zk2, zk3; cout << "Bitte geben sie eine beliebig lange Zeichenkette ein: "; cin >> zk1; cout << "Bitte geben sie eine zweite Zeichenkette an: " << endl; cin >> zk2; zk3 = zk1 + zk2; cout << zk1 << " + " << zk2 << " = " << zk3 << endl; }
header
#ifndef ZEICHENKETTE_H #define ZEICHENKETTE_H #include <iostream> #include <string> #include <cstring> using namespace std; class ClZeichenkette { public: ClZeichenkette(); ClZeichenkette(int reserviere); ~ClZeichenkette(); ClZeichenkette operator+(const ClZeichenkette &zk); friend ostream &operator << (ostream &ausgabe, ClZeichenkette &zk) { ausgabe << zk.text; return ausgabe; } friend istream &operator >> (istream &eingabe, ClZeichenkette &zk) { char puffer[1024]; eingabe >> puffer; if (zk.text!=NULL) delete zk.text; zk.laenge=strlen(puffer); zk.text=new char[zk.laenge+1]; strcpy(zk.text,puffer); return eingabe; } private: int laenge; char *text; }; #endif // ZEICHENKETTE_H
library
#include "zeichenkette.h" #include <string> #include <iostream> #include <cstring> using namespace std; ClZeichenkette::ClZeichenkette(int reserviere) { laenge=reserviere; text=new char[laenge+1]; *text='\0'; } ClZeichenkette::ClZeichenkette() { cout << "Zerstoere: " << (int)text << " = " << text << endl; if(text!=NULL) delete text; } ClZeichenkette ClZeichenkette::operator+(const ClZeichenkette &zk) { ClZeichenkette *p; p = new ClZeichenkette(laenge+zk.laenge); strcpy(p->text,text); strcat(p->text,zk.text); return *p; }
Fehlercode der mr jetzt angezeigt wird ist : undefined reference to CLZEICHENKETTE::~CLZEICHENKETTE()
danke schonmal für die Hilfe!
-
Die Meldung ist doch eindeutig: Die Definition des Destruktors fehlt. Du gibst (aus gutem Grund) an, dass du einen Destruktor brauchst, aber du schreibst nirgendwo einen. Definier ihn, und es wird funktionieren. Vermutlich soll die Zeile 16 ein Destruktor sein, aber du hast dich verschrieben. Dann würde aber wiederum der Konstruktor fehlen.
Bemerkungen:
Extrem wichtig: Wenn man meint, einen eigenen Destruktor zu benötigen, dann braucht man fast sicher auch mindestens noch einen eigenen Kopierkonstruktor und einen Zuweisungsoperator (Das nennt man "Rule of 3"). Das ist auch hier der Fall, aber in deinem Programm ist nichts davon zu sehen. Deine Ressourcenverwaltung wird nicht funktionieren, so lange du dich nicht darum kümmerst. Viel geschickter wäre es natürlich, wenn deine Zeichenkette nur die Kernfunktionalität einer Zeichenkette anbietet und die Ressourcenverwaltung einer anderen Klasse überlässt, die sich mit so etwas auskennt. Zum Beispiel einem vector oder zur Not einem Smartpointer. Dann entfällt die ganze Notwendigkeit das selber zu programmieren (Das nennt man "Rule of 0").
Extrem wichtig: Überhaupt leckt dein Programm jetzt schon Speicher ohne Ende. Beispielsweise deine reserviere-Funktion.
Wichtig: using namespace in Headern ist eine Todsünde, die das ganze Namespacekonzept kaputt macht. Nicht nur für dich, sondern für alle, die deinen Header jemals benutzen, selbst indirekt.
Stil: Deine includes scheinen eher zufällig geraten zu sein. Denk genau darüber nach, was du wo brauchst. Es macht z.B. wohl kaum Sinn, string zu includieren, wenn man dann selber std::string nachprogrammiert. Die Funktionen von cstring brauchst du nur an wenigen Stellen, aber du bindest es überall ein.
Funktionalität: Wieso schränkst du dich überhaupt auf die C-Funktionen zur Stringverarbeitung ein? Deine Klasse kennt schließlich die Länge der Zeichenkette, es besteht daher kein Bedarf für eine Nullterminierung.
-
Wie kompilierts bzw. linkst du denn? (Undefined reference ist ein Linker fehler)
außerdem glaube ich, dass du hier:
ClZeichenkette::ClZeichenkette() { cout << "Zerstoere: " << (int)text << " = " << text << endl; if(text!=NULL) delete text; }
eigentlich den Destruktor implementieren willst. Dafür fehlt die Tilde
Müsst ihr eure eigene String Klasse benutzen? Gibt es doch alles fertig.
Außerdem würde ich statt besitzender Raw Pointer mal einen blick auf Std::unique_ptr werfen.
Desweiteren sorgst du mit deinem '+' Operator für einen Memory Leak. Du erzeugst Speicher auf dem Heap und gibst eine Kopie des dereferenzierten Objektes zurück. Der Speicher der alloziert wurde, wird aber nicht freigegeben.
Allgemein sieht das leider nach einem ziemlichen C und C++ Mischmasch aus.
-
Vielen Dank für die Antowrten!
Ich stehe noch am Anfang des Lernprozesses darum passieren mir noch ein paar grobe Schnitzer.
Der Code funktioniert nun aber, danke für die Tipps!
-
Saccy92 schrieb:
Der Code funktioniert nun aber, danke für die Tipps!
Hast du mal einen Speicherprüfer wie valgrind auf das Programm angesetzt? Oder mal ein bisschen mit Objekten deiner Klasse herum gespielt, sie zum Beispiel kopiert und gegenseitig zugewiesen? Sofern du nämlich nicht dem Tipp gefolgt sein solltest, die Speicherverwaltung komplett an vector oder Smartpointer auszulagern, kann ich mir kaum vorstellen, dass du unsere Tipps in der kurzen Zeit komplett richtig umgesetzt haben kannst. Bloß weil dein einer Testfall funktioniert, heißt das nicht, dass das Programm korrekt ist!