String-Klasse
-
Is jetzt wahrscheinlich ein wenig zu spät, aber du hättest dir viel Arbeit ersparen können wenn du z.B. operator!= mit operator== implementiert hättest:
bool operator != (const String& l, const String& r) { return ! (l == r); }Noch besser: Boost.Operators
-
Danke schonmal für die Anmerkungen!!
Das mit dem Punkt 3 ist mir selber gerade aufgefallen.
Zu dem Standardkonstruktor, welchen Vorteil hätte das gegenüber dem hier?
String(char* strtext = "");Zu Punkt 2, wie kann ich das überprüfen? Was passiert, wenn das new nicht geklappt hat?
Danke für deine Ratschläge, ich werde sie schnellstmöglich umsetzen!
Alle weiteren Kritikpunkte sind herzlich willkommen!
Niko
-
Wenn es darum geht, kann man auch so etwas schreiben:
bool operator > (const String& firststr, const String& secondstr) { return secondstr < firststr; }usw.
Oder die etwas inperformante Methode der STL:
Wir bauen alles auf less auf ;).
-
Sir Niko schrieb:
Danke schonmal für die Anmerkungen!!
Das mit dem Punkt 3 ist mir selber gerade aufgefallen.
Zu dem Standardkonstruktor, welchen Vorteil hätte das gegenüber dem hier?
String(char* strtext = "");Stell Dir mal vor, dass Du eine Templateklasse hast, die eine Membervariable vom template-Typen besitzt, um temporäre Werte zu speichern. Mit Deiner Implementation, musst Du der Klasse übergeben, wie sie die Membervariable für die temporären Strings konstruieren muss. Mit einem Standardkonstrukter musst Du diesen Umstand nicht machen.
Zu Punkt 2, wie kann ich das überprüfen? Was passiert, wenn das new nicht geklappt hat?
Eigentlich sollte new dann eine Exception werfen. Musst Du halt ein try-Block um new setzen. Viele Implementationen (gerade die Älteren) setzen den Zeiger auf NULL. Das solltest Du auf jeden Fall auch abprüfen.
Niko
-
Sorry, ganz unten sollte natürlich Richie stehen, und nicht Niko :D.
Grüße
Richie
-
LOOOOOOOOOOOOL

-
ich ändere möglichst wenig.
class String { private: char* StrText; int Length; public: int GetLength(); String& operator=(const String& strtext); char& operator[](int pos); String SubStr(int posstart, int posend); String(char* strtext = ""); String(const String& strtext); virtual ~String(); friend bool operator== (const String& firststr, const String& secondstr); friend bool operator!= (const String& firststr, const String& secondstr); friend bool operator < (const String& firststr, const String& secondstr); friend bool operator <= (const String& firststr, const String& secondstr); friend bool operator > (const String& firststr, const String& secondstr); friend bool operator >= (const String& firststr, const String& secondstr); }; bool operator == (const String& firststr, const String& secondstr); bool operator!= (const String& firststr, const String& secondstr); bool operator < (const String& firststr, const String& secondstr); bool operator <= (const String& firststr, const String& secondstr); bool operator > (const String& firststr, const String& secondstr); bool operator >= (const String& firststr, const String& secondstr); int myStrlen(char* str){ int result=0; while(*str){ ++str; ++result; } return result; } ist myStrcpy(char* dst,char const* src){ while(*dst++=*scr++);//scnr } String::String(char* strtext) { this->Length = myStrlen(strtext); this->StrText = new char[i]; myStrCpy(this->StrText,strtext); } String::String(const String& strtext) { this->Length = strtext.Length; myStrCpy(this->StrText,strtext->strtext); } String::~String() { // this->Length = 0;//unnötig delete[] this->StrText; } int String::GetLength() { return Length; } String& String::operator=(const String& strtext) { if (this == &strtext) return *this; delete[] this->StrText; this->Length = strtext.Length; this->StrText = new char[Length]; myStrCpy(this->StrText,strtext->strtext); return *this; } bool operator > (const String& firststr, const String& secondstr) { //uff! nee. zu groß. muss in wenigen zeilne gehen. int l; if (firststr.Length < secondstr.Length) { l = firststr.Length; } else { l = secondstr.Length; } for (int i = 0; i < l; ++i) { if (firststr.StrText[i] > secondstr.StrText[i]) { return true; } else { if (firststr.StrText[i] < secondstr.StrText[i]) { return false; } } } if (firststr.Length > secondstr.Length) { return true; } else { return false; } } bool operator >= (const String& firststr, const String& secondstr) { //dito int l; if (firststr.Length < secondstr.Length) { l = firststr.Length; } else { l = secondstr.Length; } for (int i = 0; i < l; ++i) { if (firststr.StrText[i] > secondstr.StrText[i]) { return true; } else { if (firststr.StrText[i] < secondstr.StrText[i]) { return false; } } } if (firststr.Length >= secondstr.Length) { return true; } else { return false; } } char& String::operator[](int pos) { return this->StrText[pos]; } bool operator < (const String& firststr, const String& secondstr) { //dito int l; if (firststr.Length < secondstr.Length) { l = firststr.Length; } else { l = secondstr.Length; } for (int i = 0; i < l; ++i) { if (firststr.StrText[i] < secondstr.StrText[i]) { return true; } else { if (firststr.StrText[i] > secondstr.StrText[i]) { return false; } } } if (firststr.Length < secondstr.Length) { return true; } else { return false; } } bool operator <= (const String& firststr, const String& secondstr) { //dito int l; if (firststr.Length < secondstr.Length) { l = firststr.Length; } else { l = secondstr.Length; } for (int i = 0; i < l; ++i) { if (firststr.StrText[i] < secondstr.StrText[i]) { return true; } else { if (firststr.StrText[i] > secondstr.StrText[i]) { return false; } } } if (firststr.Length <= secondstr.Length) { return true; } else { return false; } } bool operator == (const String& firststr, const String& secondstr) { //dito if (firststr.Length != secondstr.Length) { return false; } else { for(int i = 0; i < firststr.Length; ++i) { if (firststr.StrText[i] != secondstr.StrText[i]) { return false; } } return true; } } bool operator!= (const String& firststr, const String& secondstr) { //dito if (firststr.Length != secondstr.Length) { return true; } else { for(int i = 0; i < firststr.Length; ++i) { if (firststr.StrText[i] != secondstr.StrText[i]) { return true; } } return false; } } private: String(int len){ Length=len; strtext=new char[len+1]; } public: String String::SubStr(int posstart, int posend) { String result(posend-posstart); int i=0; for(;i<posend+posstart;++i) result.strtext[i]=strtext[i-posstart]; result.strtext[i]='\0'; }soll keine mecker sein, sondern nur anregung. ich mach selber noch viel mehr falsch als du, und ich sage nicht, daß du meinen mist übernehmen sollst. aber vielleicht hilft's, deinen code ein wenig einfacher zu machen.
-
Ein paar weitere Methode wären vielleicht hilfreich.
- zum verknüpfen zweier Strings "Hallo" + " Welt" = "Hallo Welt"
- Typumwandlung toint, tofloat
-
imhotep schrieb:
Ein paar weitere Methode wären vielleicht hilfreich.
- zum verknüpfen zweier Strings "Hallo" + " Welt" = "Hallo Welt"
- Typumwandlung toint, tofloatToint und Tofloat sind IMHO kiene gute idee, dafür sind doch stringstreams zuständig.
-
du könntest die methoden, die den string unverändert lassen, const deklarieren, also
int GetLength() const;usw.
sonst könntest du diese methoden nicht anwenden, falls du mit deiner klasse einen konstanten string definierst (zB const String="Hallo").auch das this-> kannst du vor den objektvariablen weglassen. das macht der c++-compiler automatisch

was mir bei deinem code alledings ein bißchen bauchschmerzen macht, ist das new char[i] im konstruktor. wenn der string die länge 0 hat, dann allozierst du ja 0 bytes. ich bin selber noch nicht so fit in c++ und ich weiß nicht was das programm da produzieren würde, aber auf jeden fall nichts gutes

eine schnelle lösung dieses problems wäre, Length+1 bytes zu allozieren und das nul-byte mitzukopieren. dann könntest du intern auch die <cstring>-funktionen zum kopieren,vergleichen etc benutzen.
-
Konfusius schrieb:
du könntest die methoden, die den string unverändert lassen, const deklarieren
Sehr gute Idee. Und nicht nur bei Methoden, sondern auch bei Parametern, zB so
String(const char* strtext = "");Konfusius schrieb:
was mir bei deinem code alledings ein bißchen bauchschmerzen macht, ist das new char[i] im konstruktor. wenn der string die länge 0 hat, dann allozierst du ja 0 bytes. ich bin selber noch nicht so fit in c++ und ich weiß nicht was das programm da produzieren würde, aber auf jeden fall nichts gutes

Der Standard garantiert zumindest, dass bei Grösse 0 newtrotzdem eine gültige Adresse liefert.
Konfusius schrieb:
eine schnelle lösung dieses problems wäre, Length+1 bytes zu allozieren
Da er auf C-Strings setzt, sollte das Grundvoraussetzung sein.
@Sir Niko
Da sowas hier schon ein paar mal gefragt wurde, solltest du mal die Forensuche benutzen. Da wirst du sicherlich noch mehr Anregungen finden.
Ich habe deinen Code nur mal grob überflogen, es scheint mir aber, dass du zuviel Redundanz hast. Wenn du bestimmte Sequenzen öfters verwendest, dann lagere sowas in Funktionen aus.
-
Konfusius schrieb:
was mir bei deinem code alledings ein bißchen bauchschmerzen macht, ist das new char[i] im konstruktor. wenn der string die länge 0 hat, dann allozierst du ja 0 bytes. ich bin selber noch nicht so fit in c++ und ich weiß nicht was das programm da produzieren würde, aber auf jeden fall nichts gutes

das mach ich immer so. dafür erwarte ich im gegenzug aber nicht, daß delete 0; klaglos geht.