000
05.04.2003, 13:28 Uhr
Chillmaster
|
Hi
Aaaaaalso: Ich versuche gerade etwas tiefer in die C++ - Programmierung einzusteigen. In dem Buch, das ich dazu verwende wurde anhand einer selbstgeschriebenen String-Klasse demonstriert, wie man mit Arrays, Zeigern auf Arrays, Überladen von Operatoren usw. arbeitet. Hab ne Weile gebraucht, bis ich alles kapiert hab. Ich versteh nun nur eines nicht: In der Klasse wird der = - Operator überladen und zwar folgendermaßen:
C++: |
String & String::operator= (const String & rhs) { if (this == &rhs) return *this; delete[] itsString; itsLen = rhs.GetLen(); itsString = new char[itsLen + 1]; for (unsigned short i = 0; i < itsLen; i++) itsString[ i ] = rhs[ i ]; itsString[itsLen] = '\0'; return *this; }
|
Wie zu sehen ist, heißt die Klasse String. Die ersten beiden Zeilen der Klasse testen, ob auf der rechten Seite vom operator das gleiche String - Objekt steht wie auf der linken und gibt den linken String wieder zurück -> Keine Veränderung. Wenn ich den Test ausklammere (und das return this natürlich auch), und schreibe: String1 = String1 stehen hinterher lauter '=' in dem String.
Das hatte mich verblüfft, aber ich dachte, nagut, dann setzt der Compiler eben einen Standardwert nach dem Löschen mit delete[]. Und der ist eben das '=' für jede Stelle des Strings.
ABER: Wenn ich INNERHALB der Elementfunktion, welche ich oben beschrieben habe den String ausgebe stehen dort lauter | in dem String. Außerhalb (also in main, von wo aus auch der Aufruf String1 = String1 erfolgte), stehen aber trotzdem '=' im String.
Woran liegt das?
Naja, falls das Ganze keiner verstanden hat, weil ich es nicht erklären kann, hier nochmal der komplette Programmcode:
C++: |
// Listing 12.12 - Verwendung einer String - Klasse #include <iostream.h> #include <conio.h> #include <string.h>
// Rudimentäre String-Klasse class String { public: // Konstruktoren String(); String (const char * const cString); String (const String & rhs); ~String();
// Ueberladene Operatoren char operator[] (unsigned short offset) const; String & operator= (const String &);
// Allgemeine Zugriffsfunktionen unsigned short GetLen() const { return itsLen; } const char * GetString() const { return itsString; }
private: String (unsigned short); // privater Konstruktor char * itsString; unsigned short itsLen; };
// Standardkonstruktor erzeugt einen String von 0 Byte String::String() { itsString = new char[1]; itsString[0] = '\0'; itsLen = 0; }
// privater (Hilfs-)Konstruktor, wird nur von Klassenmethoden verwendet, // um einen neuen Null-String von erforderlicher Größe zu erzeugen. String::String(unsigned short len) { itsString = new char[len+1]; for (unsigned short i = 0; i <= len; i++) itsString[ i ] = '\0'; itsLen = len; }
// Konvertiert ein Zeichenarray in einen String String::String(const char * const cString) { itsLen = strlen(cString); itsString = new char[itsLen+1]; for (unsigned short i = 0; i < itsLen; i++) itsString[ i ] = cString[ i ]; itsString[itsLen] = '\0'; }
// Kopierkonstruktor String::String (const String & rhs) { itsLen = rhs.GetLen(); itsString = new char[itsLen + 1]; for (unsigned short i = 0; i < itsLen; i++) itsString[ i ] = rhs[ i ]; itsString[itsLen] = '\0'; }
// Destruktor, gibt zugewiesenen Speicher frei String::~String () { delete[] itsString; itsLen = 0; }
// Selbstzuweisung prüfen, Speicher freigeben, dann String und Größe kopieren String & String::operator= (const String & rhs) { // if (this == &rhs) // return *this; delete[] itsString; cout << "\n\tTests:\n"; cout << "\t\trhs.GetString(): " << rhs.GetString() << endl; cout << "\t\tGetString(): " << GetString() << endl; cout << "\tEnde der Tests...\n\n"; itsLen = rhs.GetLen(); itsString = new char[itsLen + 1]; for (unsigned short i = 0; i < itsLen; i++) itsString[ i ] = rhs[ i ]; itsString[itsLen] = '\0'; return *this; }
// konstanter Offset-Operator für konstante Objekte (siehe Kopierkonstruktor) char String::operator[] (unsigned short offset) const { if (offset > itsLen) return itsString [itsLen-1]; else return itsString [offset]; }
int main() { String s1("Erster Test"); cout << "s1:\t\t" << s1.GetString() << endl;
char * temp = "Hello World"; cout << "\nJetzt erfolgt die Zuweisung der beiden gleichen Strings (s1 = s1)." << endl; s1 = s1; cout << "s1:\t\t" << s1.GetString() << endl;
getch(); return 0; }
|
-- With Great Power Comes Great Responsibility Dieser Post wurde am 09.04.2003 um 16:33 Uhr von virtual editiert. |