string-klasse
-
hi!
ich brauch eine string-klasse für C++, allerdings kann ich net die vorgefertigte nehmen, da ich dies für mein OS (TodoX) brauche und da kann ich keine libs verwenden und muss alles selber machen. ich hab mir zwar schon eine komplette string-klasse geschrieben, die auch sehr umfangreich ist und funktioniert, allerdings gibts da hin und wieder probleme mit dem speicher (meistens sachen mit dem freigeben) wo er dann abstürzt
cu todo
-
Original erstellt von todo:
allerdings kann ich net die vorgefertigte nehmen, da ich dies für mein OS (TodoX) brauche und da kann ich keine libs verwendenWieso kannst du keine Libs verwenden?
-
weil ich wiegesagt ein OS schreibe und da nur sachen reinkommen können, die ich selber gecodet habe (bzw. wo mir der quellcode vorliegt) weil ich sonst nich weiß, wie es aussieht mit system-calls....
cu todo
-
Normalerweise liegt die Stringklasse aber im Quelltext vor, da Templates in der Praxis nicht vorcompiliert werden können.
-
aso, ich benutz "immer" noch borland c++ 3.1 kannst du mir die header-datei (string.h) und evtl. die cpp-datei falls die header-file nicht alles enhält mal posten oder so?? wäre nett! das geht bestimmt schneller, als wenn ich danach noch such
cu todo
-
Sag das doch. Die wirst du auf dem alten Compiler überhaupt nicht zum laufen kriegen. Naja, dann schreib halt doch deine eigene String-Klasse.
-
Naja, dann schreib halt doch deine eigene String-Klasse.
Wie schreibt man eine ordentliche Stringklasse ohne Bibliotheksfunktionen (new/malloc) zu verwenden? Da muss ich mir ja erstmal meine eigne Speicherverwaltung programmieren. Hm, aber das muss ich ja sowieso, wenn ich ein eigenes BS erstelle. Selbstgespräche?
-
ich hab doch eine eig. string-klasse geschrieben, bloß ist die nicht stabil oder es wird irgendwelcher speicher net wieder freigegeben. ich weiß auch, wo ich ein delete einfügen müsste, bloß wenn ich das mache, stürzt er mir sofort ab... naja, werd wohl ganz auf string verzichten müssen und mich wieder char *, strcpy usw. begnügen müssen... ist für ein OS sowieso besser
cu todo
-
ich hab doch eine eig. string-klasse geschrieben, bloß ist die nicht stabil oder es wird irgendwelcher speicher net wieder freigegeben. ich weiß auch, wo ich ein delete einfügen müsste, bloß wenn ich das mache, stürzt er mir sofort ab... naja, werd wohl ganz auf string verzichten müssen und mich wieder char *, strcpy usw. begnügen müssen... ist für ein OS sowieso besser
Resultiert diese Schlussfolgerung aus irgendeiner Logik heraus. Wenn ja, aus welcher mir nicht bekannten?
-
Hier, das ist vielleicht keine besonders gute oder effiziente Klasse, aber sie funktioniert immerhin!
Sie wurde halt von einem Anfänger geschrieben.
[siehe späteren Beitrag]
-
Ich weis, ich hätte z.B. die substring Methode effizienter schreiben können. Ich hätte nur ein paar Zeiger inkrementieren oder auch dekrementieren brauchen und das neue Stringobjekt hätte sich den Speicher mit dem Alten teilen können. Aber ich war mir da nicht so sicher. Denn wenn das eine Objekt gelöscht wird, dürfte es Probleme geben. Und ich weis auch, dass ich die ganze Klasse hätte besser machen können und z.B. mit den beliebten template arbeiten können. Aber das ist ja alles im Konjunktiv, denn ich schreibe lieber code den ich kapiere!
-
Ich seh haufenweise new, aber nirgends delete. Sehr fragwürdige Empfehlung, IMHO.
-
Ach ja, habe noch was vergessen. Da diese Klasse eben noch ziemlich schlecht ist, bitte ich um Verbesserungsvorschläge! Danke!
-
Nun ja, wie man am obigen Code sieht, kann man anscheinend auch eine string-Klasse ohne Speicherverwaltung schreiben.
Du müsstest deinen Speicher schon intern verwalten. So wie du das jetzt machst übergibst du die Verantwortung dem Nutzer. Er muss Speicher vereinbaren und auch wieder löschen. Das geht auf jeden Fall schief.
[ Dieser Beitrag wurde am 07.05.2003 um 17:49 Uhr von Braunstein editiert. ]
-
Original erstellt von Pogo:
Ach ja, habe noch was vergessen. Da diese Klasse eben noch ziemlich schlecht ist, bitte ich um Verbesserungsvorschläge! Danke!Vorschlag #1: Memory-Leaks entfernen (also wie Bashar gesagt hat: auch mal deleten).
Vorschlag #2: PreIncrement verwenden (also ++i anstatt i++) wenn PostIncrement unsinnig ist -> siehe FAQ.
Vorschlag #3: Mal so'n paar Sachen auf den ersten Blick korrigiertbool String::equals(String &string) const { char* value2 = string.toCharPointer(); char *p1 = value2, *p2 = value; // <- so besser bool same = true; // <- wenn du es hier schon auf true setzt sparst du dir viele Male same = true unten while(p1[0] != '\0' && p2[0] != '\0') { if(p1[0] == p2[0]) { ++p1; // <- ++p1 ist hier schneller als p1++ ++p2; } else { same = false; break; } } return same; }
-
Oh! Du hast recht. Stimmt, das habe ich ganz vergessen.
Naja, das lässt sich ja leicht "nachimplementieren".
-
Original erstellt von Braunstein:
Nun ja, wie man am obigen Code sieht, kann man anscheinend auch eine string-Klasse ohne Speicherverwaltung schreiben.So ganz ohne wird das nicht gehen...
HumeSikkins sprach ausserdem davon, dass man bei einem eigenen OS auch eine eigene Speicherverwaltung braucht...
-
Wie du an seinen Konstruktoren siehst vereinbart er keinen neuen Speicher sondern nutzt den der übergebenden Variablen.
Siehe hier:String::String(char* string) { value = string; length = getLength(string); }
Wenn in diesen Code nicht noch sehr viel fehlt, muss also die Speichervereinbarung und Löschung von der übergebenen Variablen übernommen werden und das bezeichne ich als schlecht designed.
Ciao
-
String::String() { value = "NULL"; length = 4; }
aua
-
[cpp]
bool String::equals(const String &string) const
{
char *p1 = string.toCharPointer(), *p2 = value;
while(*p1 != '\0' && *p2 != '\0') // oder besser while(*p1&&*p2)
{
if(*p1 == *p2)
{
++p1;
++p2;
}
else
{
return false;
}
}
return true;
}[/cpp]ich finde p[0] ist irgendwie unlogisch. es ist zwar das selbe wie *p - aber man (zumindest ich) erwartet bei p[0] doch irgendwie eine änderung von [0] und nicht vib p..
also laufende zeiger mit *
und über indices mit []man kanns auch anders herum machen, aber ich denke so ist es die gängige variante.
ich würde nicht zweimal equals implementieren, sondern einfach:
bool String::equals(const String &string) const { return equals(string.toCharPointer(); }
schreibendu vergisst oft const zu schreiben...
for (int i = 0; i < getLength(buffer); i++) { buffer[i] = p[c++]; c2++; } buffer[c2] = '\0';
ein memcpy wäre besser
und getLength(const char*) ist sowieso blödsinn - dafür gibt es strlen()
if (endIndex > getLength() || beginIndex > getLength() || beginIndex > endIndex) return String("ERROR");
blödsinn...
ein ERROR string hat keinen sinn.
entweder du machst n assert oder wirfst ne exception - das hier ist ein logik fehler!if (p[0] >= 97 && p[0] <= 122) p[0] -= 32;
verwende doch tolower/toupper
getLength(string.toCharPointer());
wie wäre es mit string.getLength() ?
du hast einige sehr verwirrende funktionen - du solltest in denen den code vielleicht kommentieren und/oder lesbarer schreiben...
du brauchst keine statusvariablen um
return same;
zu schreiben zu können - du kannst ja statt same=false; einfach return false; schreibendu solltest keine memory leaks haben...
und die klasse sollte den speicher selber verwalten und nicht der user
du solltest nicht sooft den selben code schreiben - probiere eine funktion mit hilfe einer anderen zu implementieren
das ist mir beim drüberfliegen aufgefallen