String-Klasse als Vorbild gesucht
-
Erhard Henkes schrieb:
@ groovemaster2002: poste deine Klasse doch mal hier, damit wir sie so richtig zerlegen können
War das ironisch oder ernst gemeint?
-
groovemaster2002 schrieb:
Erhard Henkes schrieb:
@ groovemaster2002: poste deine Klasse doch mal hier, damit wir sie so richtig zerlegen können
War das ironisch oder ernst gemeint?
Eher sarkastisch
-
groovemaster2002 schrieb:
die teilweise schneller ist als die std::string Implementation von MS.
wurde die STL von MS implementiert ?
-
DEvent schrieb:
groovemaster2002 schrieb:
die teilweise schneller ist als die std::string Implementation von MS.
wurde die STL von MS implementiert ?
Es gibt verschiedene Implementierungen, von Microsoft gibt es soweit ich weiß keine. Die Standardbibliothek die mit VC mitgeliefert wird, stamm von Dinkumware.
-
Hi!
goovemaster2002 schrieb:
6. Zwinge deiner Klasse im Header nicht den std Namensraum auf und verwende std:: stattdessen.
Das hat Erhard Henkes so gemacht. Eigentlich ist der namensraum std nur in der CPP-Datei global bekannt gemacht.
Danke für deine Vorschläge, da ich jetzt etwas ferien habe werde ich die Stringklasse mal erneuern. Habe mal die im Stroustrup kurz überflogen, die sah ganz interessant aus. Dort wird der String über den Konstruktor ohne Argument auch mit einem Leerstring initialisiert.
Code-Hacker
-
Die Vergleichoperatoren greifen auf strcmp zurück. Würde mich mal interessieren was die std::string-Klasse wesentlich anders macht.
Naja, normalerweise würde ich erstmal die länge der Strings vergleichen (die ja extra gespeichert ist). Wenn die Länge zweier strings verschieden ist, kann der inhalt nicht gleich sein.
-
Hi!
Stimmt.
Außerdem prüft strcmp alle Fälle und nicht nur Gleichheit. Deswegen kann man dort wieder jedes Zeichen nur mit == vergleichen und bei ungleichheit einfach false zurückgeben, ansonsten true.Code-Hacker
-
if(string) delete[](string); len=v.size(); bufsize=FWDBUFFER+len+1; string=new(char[bufsize]);
Nun stell dir mal vor, dass new eine bad_alloc exception werfen würde. Dann wäre die Stringklasse irreparabel futsch. Ausserdem wäre es besser auch bei einem leeren String Speicher anzulegen, damit fällt der ständige Test ob string non NULL ist weg.
Erhard Henkes schrieb:
// [] char MyString::operator[]( int i ) const { if( i >= 0 && i < getLaenge() ) { return pData_[i]; } else { return '\0'; } }
Meinst du dies hier? Eine Referenz auf einen char? hmmm.
Ich denke, nein.
Ich würde bei einer Bereichsüberschreitung ne Exception werfen, aber wenn man das nicht will gibt es eine eher gute Alternative. Die Stringklasse kriegt einen statischen char Member und wenn der Bereich überschritten ist dann setzt du ihn auf 0 und gibst ihn als Referenz zurück. Wenn der Benutzer ihn nun auf non 0 setzt ist nicht schlim wenn du ihn wieder verwendest setzt du ihn ja wieder darauf.
EString &EString::operator=(const char *s) { replace(s); return(*this); }
Hier würd ich die replace Funktion direkt in den operator=(const char*) packen (also nicht ihn eine eigene Funktion auslagern). Das ist ja alles was der operator=(const char*) tut, und du kannst ihn ja auch aus anderen Methoden aus aufrufen.
Also ich bevorzuge std::string (auch vom Design her).
-
Ich würde bei einer Bereichsüberschreitung ne Exception werfen, aber wenn man das nicht will gibt es eine eher gute Alternative. Die Stringklasse kriegt einen statischen char Member und wenn der Bereich überschritten ist dann setzt du ihn auf 0 und gibst ihn als Referenz zurück. Wenn der Benutzer ihn nun auf non 0 setzt ist nicht schlim wenn du ihn wieder verwendest setzt du ihn ja wieder darauf.
Von so viel Toleranz halte ich nichts. Da muss eiskalt eine Exception fliegen, oder (wenn die Performance mal wieder soooo wichtig ist) ein assert mit dem Risiko, im Release-Build UB zu haben.
Fluchtwerte halte ich hier grundsätzlich für falsch. Das ist nichts, was mal passieren kann (die Rede ist von einem ungültigen Index), sondern etwas, was absolut nicht passieren darf.
-
Irgendwer schrieb:
Ich würde bei einer Bereichsüberschreitung ne Exception werfen [...]
Optimizer schrieb:
Von so viel Toleranz halte ich nichts. Da muss eiskalt eine Exception fliegen [...]
Ist doch schön, wenn man sich so einig ist. :p
Aber mal Spass beiseite. Ich hab in meiner String Klasse selbst so einen static Dummy. Auch wenn eine Exception sicherlich nicht falsch ist, so halte ich das bei Elementzugriffen für ziemlich harten Tobak (zumindest im Release Build). Da geht einem der Spass an C++ gegenüber Sprachen wie VB doch glatt verloren.Vielleicht liegt es aber auch nur daran, dass ich Exceptions normalerweise nur in Initialisierungs/Deinitialisierungsphasen (wie ctor / dtor) verwende, wo Performance nur eine untergeordnete Rolle spielt.
Shlo schrieb:
groovemaster2002 schrieb:
Erhard Henkes schrieb:
@ groovemaster2002: poste deine Klasse doch mal hier, damit wir sie so richtig zerlegen können
War das ironisch oder ernst gemeint?
Eher sarkastisch
Für Sarkasmus wars mir noch zu harmlos. :p
Code-Hacker schrieb:
Habe mal die im Stroustrup kurz überflogen, die sah ganz interessant aus. Dort wird der String über den Konstruktor ohne Argument auch mit einem Leerstring initialisiert.
Imo ist es eine gute Idee, grundsätzlich Speicher für die String Daten im ctor zu reservieren. Wie Irgendwer schon sagte, kannst du dir dann den ganzen if (!string) Teil sparen und erweiterst (oder verkürzt) lediglich den Speicherbereich bei Bedarf.
-
Vielleicht liegt es aber auch nur daran, dass ich Exceptions normalerweise nur in Initialisierungs/Deinitialisierungsphasen (wie ctor / dtor) verwende, wo Performance nur eine untergeordnete Rolle spielt.
Auu, nicht so hart bitte. Ein Dtor sollte keine Exceptions werfen! Und das war ja wohl nicht dein Ernst, dass aus Performancegründen keine Exceptions verwendest! Wenn ein Fehler auftritt führt das auf lange Sicht immer zu einem Abbruch der Prozedur in der er aufgetreten ist und dann ist die Performance eh kein Thema mehr.
-
Irgendwer schrieb:
Auu, nicht so hart bitte. Ein Dtor sollte keine Exceptions werfen!
Jau, hast natürlich Recht mit dem dtor. Keine Ahnung was mich da geritten hat, meinte auch eher nur ctor.
Irgendwer schrieb:
Und das war ja wohl nicht dein Ernst, dass aus Performancegründen keine Exceptions verwendest!
Doch!
Irgendwer schrieb:
Wenn ein Fehler auftritt führt das auf lange Sicht immer zu einem Abbruch der Prozedur in der er aufgetreten ist und dann ist die Performance eh kein Thema mehr.
Das ist schon richtig, nur hab ich das Gefühl, dass zu viele Leute Exceptions missbrauchen und dort verwenden, wo sie gar nicht notwendig sind. Exception bedeutet Ausnahme, und nicht jeder Fehler führt zu einem nicht wiederherstellbaren Ausnahmezustand eines Objektes. Ausserdem bringen Exceptions generell einen Laufzeitoverhead mit, egal ob sie geworfen werden oder nicht. Dieser hängt natürlich von der Code Struktur und der Implementation ab. Vor einiger Zeit hatte ich mal einen relativ einfachen Benchmark gemacht in einem try / catch Block. Nachdem ich diesen weggelassen hatte, lief das ganze ca. 3 mal zu schnell. Mag jetzt ein Extrembeispiel sein, zeigt aber was generell möglich ist.
-
Keiner hat von try-catch geredet. Ich schreibe bestimmt nicht
try { String x = "Hoi!"; char z = x[-1]; } ...
Ohne try bringt die Exception keinen Overhead, außer sie wird geworfen (und die if-Abfrage natürlich).
Die if-Abfrage hast du aber auch bei deiner Fluchtwert-Methode.
Und einen Fluchtwert zurückzuliefern ist ja wohl ne Todsünde. Das Zeichen an Positon 793265 ist nun mal nicht '\0' oder sonst irgendwas. Wenn jemand Mist baut, muss es knallen und zwar sofort.
Sonst freut sich jemand anders, der dann 3 Stunden lang herausfinden darf, warum der String vorzeitig mit einer '\0' endet.
-
Optimizer schrieb:
Und einen Fluchtwert zurückzuliefern ist ja wohl ne Todsünde
Und bei einem ctor auf normalem Wege sowieso nicht machbar.
Optimizer schrieb:
Keiner hat von try-catch geredet.
Imho sorgt catch schon für Overhead. Und wie willst du denn ohne catch Exceptions fangen? Und was passiert, wenn ich kein try verwende? Können dann Exceptions überhaupt gefangen werden?
-
Ja, try-catch sorgt für Overhead. Hat aber keiner gesagt, dass die Exception gefangen werden muss.
Optimizer schrieb:
Das Zeichen an Positon 793265 ist nun mal nicht '\0' oder sonst irgendwas. Wenn jemand Mist baut, muss es knallen und zwar sofort.
Ich will nur darauf hinaus. Ob du das jetzt mit einer ungefangenen Exception oder einem assert machst, ist zumindest mir egal.
Wichtig ist nur, dass das Programm so schnell wie möglich abkackt und nicht erst über 50 Umwege 2 Jahre später. Dann findet man den Fehler nämlich nicht mehr.
-
Optimizer schrieb:
Ja, try-catch sorgt für Overhead. Hat aber keiner gesagt, dass die Exception gefangen werden muss.
Ja dann hat es doch aber auch keinen Sinn, dass ich sie werfe? Was passiert denn, wenn eine Exception geworfen wird und niemand fängt sie?
-
Das Programm kackt ab?
-
Nein. Das Programm wird *korrekt* beendet, mit allen Dtors...das ist IMHO schon ein Unterschied
Außerdem verwendet man natürlich manchmal try/catch, aber eben nicht oft und gerne ein paar Ebenen höher...
-
operator void schrieb:
Nein. Das Programm wird *korrekt* beendet, mit allen Dtors...das ist IMHO schon ein Unterschied
Tatsache. Das sollte man nicht unerwähnt lassen.
-
operator void schrieb:
Nein. Das Programm wird *korrekt* beendet, mit allen Dtors...das ist IMHO schon ein Unterschied
sind wir uns da ganz sicher, daß das programm korrekt beendet wird, wenn keiner die excpetion fängt?