Einleitung
Überladen von binären Operatoren
Überladen von logischen Operatoren
Überladen von unären Operatoren
Überladen der Operatoren ++, - - und des cast-Operators
const Objekte und überladene Operatoren
Sonstige Hinweise zum Überladen von Operatoren
Beispiel und Übung
Genauso wie in der letzten Lektion der Zuweisungsoperator '=' überladen wurde, können für ein Objekte fast alle anderen Operatoren überladen werden, mit folgenden Ausnahmen:
Ebenfalls nicht überladbar ist das Präprozessor-Symbol '#', aber das versteht sich ja fast von selbst, da die Präprozessoranweisung vor dem Compilerlauf durch den Präprozessor schon ersetzt wird.
Um einen Operator zu überladen stehen zwei prinzipielle Vorgehensweisen zur Verfügung:
Wird ein binärer Operator (das sind Operatoren mit zwei Operanden wie
z.B. '+' oder '*') überladen, so wird in der
Regel folgende Memberfunktion hierfür eingesetzt:
| RVAL CANY::operator OSYMBOL (DTYP); |
RVAL ist der Returntyp des Operators und OSYMBOL das Symbol des zu überladenden Operators (z.B. '+' für die Addition) für die Klasse CANY. Da die Memberfunktion im Kontext des ersten, linken Operanden aufgerufen wird, gibt DTYP den Datentyp des zweiten, rechten Operanden an.
Beispiel:
Für die Klasse Complex soll der Plus-Operator definiert werden, so dass folgende Operation möglich ist:
comp3 = comp1 + comp2;
Als erstes wird der Returntyp des überladenen Operators bestimmt. Da eine Addition von zwei Complex-Objekten ebenfalls wieder ein Complex-Objekt ergibt, muss die Memberfunktion ein Complex Objekt zurückgeben, welches das Ergebnis enthält. Damit besitzt die Memberfunktion folgende Deklaration:
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
Complex operator + (const Complex& op2) const;
};
|
Die Memberfunktion ist als const Memberfunktion deklariert, da sie die Eigenschaften des linken Operanden, in dessen Kontext sie aufgerufen wird, ja nicht verändert.
Danach kann die Memberfunktion definiert werden. Eine Addition von zwei Complex-Objekten addiert einfach die Real- und Imaginäranteile der beiden Objekte. Doch hier lauert eine Fehlerfalle, die auf den ersten Blick nicht gleich ersichtlich ist. Sehen Sie sich einmal die nachfolgende korrekte Definition der Memberfunktion genau an.
// Überladener Plus-Operator Complex Complex::operator + (const Complex& op2) const; { // temp. Hilfsobjekt mit akt. Objekt initialisieren (Aufruf copy-ctor) Complex temp(*this); // 2. Operanden hinzuaddieren temp.real += op2.real; temp.imag += op2.imag; // temp. Objekt zurückgeben return temp; } |
Zuerst wird ein lokales Objekt der Klasse Complex definiert, das bei seiner Definition auch gleich mit dem aktuellen Objekt (dies ist der linke Operand des + Operators!) initialisiert wird (Aufruf des Kopier-Konstruktors). Anschließend wird zu diesem lokalen Objekt das zweite Objekt (rechter Operand der + Operators) hinzuaddiert. Sie müssen hier unbedingt ein temporäres Hilfsobjekt zu Hilfe nehmen, denn eine Addition von zwei Objekten darf niemals den Inhalt der beiden als Operanden verändern!
|
|
Sehen wir uns ein weiteres Beispiel des überladenen Plus-Operators der Klasse Complex an. Anstelle zwei Complex-Objekte zu addieren, soll jetzt zu einem Complex-Objekt ein double-Wert addieren werden, d.h. folgende Operation soll erlaubt sein:
comp2 = comp1 + 1.2;
Am Returntyp der Memberfunktion ändert sich gegenüber vorher nichts, da auch hier das Ergebnis der Addition wiederum ein Complex-Objekt ist. Lediglich der Datentyp des Parameters der Memberfunktion ändert sich, da er den Datentyp des zweiten (rechten) Operanden widerspiegelt. In unserem Fall hier ist der Datentyp ein double. Im nachfolgenden Beispiel wird der double-Wert nur zum Realanteil der komplexen Zahl addiert.
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
Complex operator+ (double val) const;
};
// Überladener Plus-Operator
Complex Complex::operator + (double val) const
{
// temp. Hilfsobjekt definieren und mit akt. Objekt initialisieren
Complex temp(*this);
// Operand hinzuaddieren
temp.real += val;
// temp. Objekt zurückgeben
return temp;
}
|
|
comp2 = 1.2 + comp1; können Sie nicht mit einer Memberfunktion realisieren! Wie bereits erwähnt, wird die Operator-Memberfunktion im Kontext des linken Operanden aufgerufen, und das ist hier im Kontext von double. Da Sie für die Standard-Datentypen keine Operatoren überladen können, müssen Sie für diese Operation auf eine normale Funktion zurückgreifen. Mehr dazu nun. |
Betrachten wir nun den Fall, dass der Operator durch eine normale Funktion überladen wird und nicht durch eine Memberfunktion. Wie bereits am Anfang der Lektion erwähnt, wird hierfür eine friend-Funktion benötigt. Die Besonderheit einer friend-Funktion liegt darin, dass sie Zugriff auf alle Member einer Klasse (auch auf die private-Member!) besitzen. Mehr zu friend-Funktionen später im Kurs noch.
Wird ein binärer Operator durch eine normale Funktion überladen, so wird in der Regel folgende Funktion hierfür eingesetzt:
| RVAL operator OSYMBOL (DTYP1 Op1, DTYP2 Op2); |
RVAL ist der Returntyp des Operators und OSYMBOL das Symbol des zu überladenden Operators (z.B. '+' für die Addition). Da die Funktion nun nicht mehr zur Klasse gehört, und damit implizit der Datentyp des linken Operanden definiert ist, benötigt sie auch zwei Parameter. Der erste Parameter gibt hierbei den linken Operanden und dessen Datentyp an und der zweite Parameter den rechten Operanden und dessen Datentyp.
Sehen wir uns an, wie der Plus-Operator für die Klasse Complex durch eine normale Funktion überladen wird, um zu einem Complex-Objekt einen double-Wert zu addieren. Beachten Sie bitte die Deklaration der friend-Funktion innerhalb der Klasse Complex. Die friend-Deklaration gleich bis auf das vorangestellte Schlüsselwort friend der Deklaration der Operatorfunktion.
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
....
// Funktion als friend-Funktion deklarieren
friend Complex operator + (const Complex& op1, double val);
};
// Überladener Plus-Operator
Complex operator+ (const Complex& op1, double val)
{
// temp. Hilfsobjekt
Complex temp(op1);
// 2. Operanden hinzuaddieren
temp.real += val;
// temp. Objekt zurückgeben
return temp;
}
|
Die Funktion muss als Returnwert ein Complex-Objekt mit dem Ergebnis der Addition liefern. Im ersten Parameter erhält die Funktion eine Referenz auf den linken Operanden des Operators, in unserem Fall also eine Referenz auf ein Complex-Objekt. Und da der zweite Parameter den rechten Operanden repräsentiert, muss hier ein double-Parameter stehen. Der Ablauf der Funktion selbst entspricht dem vorherigen Beispiel.
Aber Achtung!
|
comp2 = comp1 + 1.2; Wollen Sie auch Operationen vom Typ comp2 = 1.2 + comp1; durchführen, so müssen Sie eine weitere friend-Funktion definieren, bei der die beiden Parameter vertauscht sind, d.h. Complex operator+ (double val, const Complex& op2); |
Oftmals ist es erforderlich, zwei Objekte miteinander vergleichen zu können. Da im C++ Standard nicht definiert ist, wie Objekte miteinander verglichen werden, müssen auch hierfür die entsprechenden Operatoren überladen werden, um z.B. folgende Anweisungen schreiben zu können:
if (comp1 == comp2)
...
if (comp1 != comp2)
....
Beide Operatoren müssen als Ergebnis einen bool-Wert
zurückliefern. Und damit ergeben sich die nachfolgend dargestellten
Vergleichs-Memberfunktionen. Sehen Sie sich einmal an wie der !=
Operator überladen wurde. Er ruft den überladenen ==
Operator auf und negiert lediglich dessen Ergebnis. Verwenden Sie soweit
wie möglich bereits bestehenden Code!
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
bool operator == (const Complex& op2) const;
bool operator != (const Complex& op2) const;
};
// Überladener == Operator
bool Complex::operator == (const Complex& op2) const
{
return ((real == op2.real) &&
(imag == op2.imag));
}
// Überladener != Operator
bool Complex::operator != (const Complex& op2) const
{
return !operator==(op2);
}
|
Kommen wir nun zum Überladen von unären Operatoren wie z.B. dem
NOT-Operator '!'. Auch diese Operatoren können entweder
durch eine nicht-statische Memberfunktion der Klasse oder eine Funktion
überladen werden.
Um einen unären Operator durch eine nicht-statische Memberfunktion zu überladen wird in der Regel folgende Memberfunktion verwendet:
| RVAL CANY::operator OSYMBOL (); |
RVAL ist der Returntyp des Operators und OSYMBOL wiederum das Symbol des zu überladenden Operators (z.B. '!' für die NOT-Operation) der Klasse CANY. Da unäre Operatoren nur einen Operanden besitzen, benötigt die Memberfunktion keine weiteren Parameter.
Für die bekannte Klasse Complex soll der Vorzeichenoperator überladen werden, so dass folgende Operation definiert ist:
comp2 = -comp1;
Beachten Sie bitte, dass es sich hier um den Vorzeichenoperator und nicht um den Minus-Operator handelt! Beide besitzen zwar das gleiche Symbol, der Minus-Operator benötigt jedoch zwei Operanden und der Vorzeichenoperator nur einen. Da das Ergebnis des Vorzeichenoperators immer vom Typ des Operanden ist, muss die Operator-Memberfunktion auch ein Complex-Objekt zurückliefern. Im Beispiel kehrt der Vorzeichenoperator die Vorzeichen des Real- und Imaginäranteils um. Achten Sie beim Überladen von Operatoren auch immer darauf, wann Sie Operanden verändern dürfen und wann nicht!
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
Complex operator -() const;
};
// Überladener Vorzeichenoperator
Complex Complex::operator- () const
{
Complex temp;
temp.real = -real;
temp.imag = -imag;
return temp;
}
|
Wird ein unärer Operator durch eine normale Funktion überladen, so wird in der Regel folgende Funktion hierfür eingesetzt:
| RVAL operator OSYMBOL (CAny& Op1); |
RVAL ist wieder der Returntyp des Operators und OSYMBOL das Symbol des zu überladenden Operators. Da die Funktion nun nicht mehr zur Klasse gehört, muss sie wiederum eine friend-Funktion der Klasse sein und benötigt einen Parameter. Dieser Parameter gibt den Operanden an und ist immer vom Typ der Klasse, für die der Operator überladen wird.
Überladen wir den NOT-Operator '!' für die Klasse Complex durch eine normale Funktion um folgende Abfrage zu ermöglichen:
if (!comp1)
....
Der NOT-Operator muss laut C++ Standard einen bool-Wert zurückliefern, denn entweder ist die Bedingung erfüllt oder nicht. Als Parameter erhält die Funktion eine const Referenz auf den Operanden. Der NOT-Operator liefert im Beispiel dann true zurück, wenn sowohl der Real- wie auch der Imaginäranteil 0.0 enthält.
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
....
// Funktion als friend-Funktion deklarieren
friend bool operator ! (const Complex& op);
};
// Überladener NOT-Operator
bool operator! (const Complex& op)
{
return ((op.real == 0.0) && (op.imag == 0.0));
}
|
Sehen wir uns nun einmal das Überladen von einigen besonderen Operatoren an. Verwiesen sei an dieser Stelle noch auf die nächste Lektion, die ebenfalls das Überladen von speziellen Operatoren behandelt.
Einen Sonderfall beim Überladen von unären Operatoren stellen die
Operatoren ++ und -- dar. Da sie sowohl als
Präfix (++X) wie auch als Postfix (X++) auftreten können, müssen hier
beim Überladen zwei verschiedene Memberfunktionen verwendet werden.
Um den Präfixoperator ++ zu überladen, wird die im nachfolgenden Beispiel angegebene Memberfunktion eingesetzt. Diese Memberfunktion muss eine Referenz auf das aktuelle Objekt zurückgeben, damit z.B. folgende Operation möglich ist:
comp2 = ++comp1;
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
Complex& operator ++();
};
// Überladener Präfixoperator ++
Complex& Complex::operator++ ()
{
++real;
++imag;
return *this;
}
|
Beachten Sie beim Präfixoperator, dass zuerst die Addition ausgeführt und das Ergebnis daraus zurückgeliefert wird. Außerdem muss der Operator hier den Operanden (sprich das Objekt, in dessen Kontext die Memberfunktion aufgerufen wurde) verändern, so dass hier kein temporäres Hilfsobjekt, wie z.B. beim + Operator, benötigt wird.
Soll der Postfixoperator überladen werden, so erhält die Memberfunktion einen Dummy-Parameter vom Typ int. Auch hier muss der überladene Operator wieder ein entsprechendes Complex-Objekt zurückliefern.
comp2 = comp1++;
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
Complex operator ++(int);
};
// Überladener Postfixoperator ++
Complex Complex::operator++ (int)
{
Complex temp(*this); //copy-ctor
++real;
++imag;
return temp;
}
|
Beachten Sie beim Überladen dieses Operators, dass der Ursprungswert des Objekts zurückgegeben werden muss, da der Postfixoperator die Addition erst nach der Auswertung des Objekts durchführen darf. Wenn Sie sich nicht mehr sicher über den Unterschied zwischen X++ und ++X sind, dann hier nachschauen.
|
|
Durch die Definition von cast-Operatoren kann dem Compiler mitgeteilt werden, wie ein Objekt in einen anderen Datentyp zu konvertieren ist. Die allgemeine Syntax für eine solche Typkonvertierung mittels einer nicht-statischen Memberfunktion lautet:
| CANY::operator NEWDTYP (); |
NEWDTYP gibt den Datentyp an, in den ein Objekt der Klasse CANY konvertiert werden soll. Am Besten sehen wir uns dies auch anhand eines Beispiels an.
Ausgangsbasis für dieses Beispiel ist wiederum die Klasse Complex. Ziel der Typkonvertierung ist es, folgende Anweisung schreiben zu können:
double val = comp;
wobei comp ein Objekt der Klasse Complex sein soll. Damit obige Anweisung durch den Compiler richtig aufgelöst werden kann, müssen wir ihm mitteilen, wie ein Complex-Objekt in einen double-Wert zu konvertieren ist. Bei dieser Konvertierung ist NEWDTYP ist der Datentyp double und damit ergibt sich die im Beispiel dargestellte Operator-Memberfunktion. Die Typkonvertierung erfolgt hier durch ziehen der Wurzel aus der Addition der quadrierten Anteile.
class Complex
{
double real, imag;
....
public:
....
operator double () const;
};
// Typkonvertierung Complex -> double
Complex::operator double () const
{
return static_cast<double>(sqrt(real*real + imag*imag));
}
|
Beachten Sie, dass die Operator-Memberfunktion keinen Returntyp besitzt und eine const-Memberfunktion ist. Würden Sie hier keine const-Memberfunktion verwenden, so könnten Sie kein const Complex Objekt in einen double-Wert konvertieren.
Sehen wir uns das Überladen von Operatoren noch einmal genauer an, und zwar im Zusammenhang mit const-Objekten. Wie Sie ja bereits wissen, lautet die allgemeine Memberfunktion zum Überladen von Operatoren:
| RVAL CANY::operator OSYMBOL (DTYP); |
Wie bereits des Öfteren erwähnt, erfolgt der Aufruf des Operators immer im Kontext des linken Operanden und der rechte Operand wird als Parameter an die Memberfunktion übergeben. Nehmen wir jetzt einmal an, Sie wollen für eine Klasse CAny den Plus-Operator überladen und hätten zwei Objekte dieser Klasse definiert und wollen die angegebenen Operationen durchführen:
CAny ncObject1, CRes;
const CAny cObject2;
CRes = ncObject1 + ncObject1;
CRes = ncObject1 + cObject2;
CRes = cObject2 + ncObject1;
CRes = cObject2 + cObject2;
Welche Operator-Memberfunktionen müssen Sie letztendlich definieren damit auch alle Operationen definiert sind?
Nachfolgend sehen Sie die Operator-Memberfunktionen in der Reihenfolge, in der Sie für die obigen Operationen aufgerufen werden. Ist der zweite Operand ein const-Objekt, so muss damit der Parameter der Operator-Memberfunktion auch ein const sein. Ist dagegen der erste Operand ein const, so muss die Operator-Memberfunktion selbst const sein. Da ein const-Objekt laut Definition nicht verändert werden, kann es also nur Memberfunktionen verwenden die dies auch sicherstellen. Und das sind const-Memberfunktionen.
class Complex
{
double real; // Realanteil
double imag; // Imaginäranteil
public:
....
Complex operator + (Complex& op2);
Complex operator + (const Complex op2);
Complex& operator + (Complex& op2) const;
Complex& operator + (const Complex op2) const;
};
|
Aber keine Panik! Sie müssen nicht immer alle vier Operator-Memberfunktionen für überladene Operatoren definieren. Ein nicht-const Objekt kann jederzeit durch den Compiler in ein const-Objekt konvertiert werden (aber nicht umgekehrt). Und damit würde im Prinzip die letzte Memberfunktion alleine ausreichen. Ob dies aber für alle Operatoren ausreicht hängt vom Anwendungsfall ab.
|
|
Zum Schluss dieser Lektion noch drei Hinweise:
= und *
überladen, so können Sie trotzdem nicht die Kurzschreibweise
*= verwenden. Sie müssen hierzu den Operator *=
explizit überladen.Und sollten Sie noch Zweifel haben, wann ein überladener Operator eine Referenz zurückliefern muss und wann ein Objekt, so können Sie sich an folgender Daumregel orientieren:
|
|
|
|
Operator |
Funktion |
|
++ |
Verschiebt ein Rechteck um eine Einheit in X- und Y-Richtung. |
|
& |
Verundet zwei Rechtecke. Es wird hierbei die gemeinsame Fläche der beiden Rechtecke berechnet und als Rect-Objekt zurückgegeben. |
|
== |
Vergleicht ob zwei Rechtecke identisch sind, d.h. die gleiche Position und Ausdehnung besitzen. |
|
! |
Stellt fest ob das Rect-Objekt eine Fläche besitzt. |
In der main() Funktion werden zwei nicht identische Rechtecke definiert. Diese Rechtecke werden mithilfe des überladenen == Operators auf Gleichheit überprüft und das Ergebnis der Überprüfung dann ausgegeben. Anschließend wird das erste Rechteck mit dem Operator ++ in X/Y-Richtung um eine Einheit verschoben. Aus den beiden Rechtecken wird dann mittels des & Operators die Schnittfläche gebildet und diese einem weiteren Rechteck Objekt zugewiesen. Zum Schluss wird noch durch Anwendung des ! Operators überprüft, ob die ermittelte Schnittfläche nicht leer ist und diese ausgegeben.
|
1. Rechteck: |
// Beispiel zu überladenen Operatoren // Zuerst Dateien einbinden #include <iostream> using std::cout; using std::endl; // Klassendefinition class Rect { short xPos, yPos; // Position short width, height; // Breite und Höhe public: Rect(); // ctors Rect(short x, short y, short w, short h); Rect(const Rect& source); void PrintRect()const; // Ausgabe des Rechtecks Rect operator ++(int); // Verschiebt Rechteck um eine X/Y-Position Rect operator & (const Rect& op2) const; // Verundet zwei Rechtecke bool operator ==(const Rect& op2) const; // Vergleicht zwei Rechtecke bool operator !() const; // Prüft auf leeres Rechteck ab }; // Definition der Memberfunktionen // 1. Konstruktor (Standard Konstruktor) Rect::Rect() { xPos = yPos = width = height = 0; } // 2. Konstruktor // Erhält als Parameter die Rechteck-Daten als 4 short Werte Rect::Rect(short x, short y, short w, short h) { xPos = x; yPos = y; width = w; height = h; } // 3. Konstruktor // copy-ctor Rect::Rect(const Rect& source) { xPos = source.xPos; yPos = source.yPos; width = source.width; height = source.height; } // Ausgabe der Rechteck Daten void Rect::PrintRect() const { cout << "Rechteck auf (" << xPos << "," << yPos << ") "; cout << "Grösse: (" << width << "," << height << ")\n"; } // Verschiebt Rechteck um eine X/Y-Position // Achtung Postfixoperator! // Darf keine const-Memberfunktion sein da das Objekt // ja verändert wird! Rect Rect::operator ++(int) { // Hilfsobjekt zur Aufnahme der akt. Werte // Ruft copy-ctor auf Rect orig(*this); // Nun erst Position verändern xPos++; yPos++; // Ursprungswerte zurückgeben return orig; } // Verundet zwei Rechtecke // Das daraus resultierende Rechtecke enthält die Fläche, // die beiden Rechtecken gemeinsam ist Rect Rect::operator & (const Rect& op2) const { // Resultierendes Rechteck Rect result; // Hilfsvariablen short end1, end2; // Grösste X-Position ist resultierende X-Position result.xPos = (op2.xPos>xPos) ? op2.xPos : xPos; // X-Positionen der rechten Kante berechnen end1 = xPos+width; end2 = op2.xPos+op2.width; // Kleinste X-Position bestimmte Breite des result. Rechtecks result.width = (end1>end2) ? end2-result.xPos : end1-result.xPos; // Nun das gleiche Spiel mit der Y-Position und der Höhe result.yPos = (op2.yPos>yPos) ? op2.yPos : yPos; end1 = yPos+height; end2 = op2.yPos+op2.height; result.height = (end1>end2) ? end2-result.yPos : end1-result.yPos; // Falls keine gemeinsame Fläche vorhanden ist // leeres Rechteck setzen if ((result.width <= 0) || (result.height <= 0)) { result.width = result.height = 0; result.xPos = result.yPos = 0; } return result; } // Vergleicht zwei Rechecke bool Rect::operator ==(const Rect& op2) const { // Rechtecke sind gleich wenn Koordinaten und Ausdehnung gleich sind if ((xPos == op2.xPos) && (width == op2.width) && (yPos == op2.yPos) && (height == op2.height)) return true; else return false; } // Prüft ab, ob das Rechteck eine Fläche besitzt bool Rect::operator ! () const { if ((width == 0) || (height == 0)) return true; else return false; } // main () Funktion int main() { // Zwei Rect Objekte erstellen Rect *pFirstRect = new Rect(10,20,100,200); Rect *pSecondRect = new Rect(50,50,100,200); // Rechteckdaten ausgeben cout << "1. Rechteck:\n"; pFirstRect->PrintRect(); cout << "2. Rechteck:\n"; pSecondRect->PrintRect(); // Rechtecke vergleichen if (*pFirstRect == *pSecondRect) cout << "Rechtecke sind gleich\n"; else cout << "Rechtecke sind unterschiedlich\n"; // Erstes Objekt verschieben // Klammerung unbedingt beachten! (*pFirstRect)++; cout << "1. Rechteck um eins verschoben:\n"; pFirstRect->PrintRect(); // Neues Rechteck aus der gemeinsamen Fläche der beiden // Rechtecke bilden Rect mergedRect = *pFirstRect & *pSecondRect; // Abprüfen, ob beide Rechtecke eine gemeinsame Fläche hatten if (!mergedRect) cout << "Keine Überschneidung der beiden Rechtecke!\n"; else { cout << "Rechtecke überschneiden sich! Gemeinsame Fläche:\n"; mergedRect.PrintRect(); } delete pFirstRect; delete pSecondRect; } |
Erweitern Sie die in vorherigen Übung erstellte Klasse CString um den Operator ==, um zwei CString-Objekte vergleichen zu können.
Ersetzen Sie dann die beiden AddString(...) Memberfunktionen der Klasse durch entsprechendes Memberfunktionen, die den Operator + überladen.
Erstellen Sie im main() zwei CString-Objekte, wobei das erste CString-Objekt bei seiner Definition mit dem Text "Es waren" zu initialisieren ist und das zweite leer bleibt. Geben Sie beide Objekte zur Kontrolle aus.
'Addieren' Sie zum ersten CString-Objekt den Text " einmal zwei Ameisen" und zum zweiten den Text "die wollten nach Amerika reisen" hinzu. Geben Sie beide Objekte erneut aus.
Vergleichen Sie dann beide CString-Objekte mittels einer if-Abfrage auf Gleichheit und geben das Ergebnis der Abfrage aus.
Zum Schluss weisen Sie dem ersten CString-Objekt das zweite CString-Objekt zu und vergleichen nun nochmals die beiden Objekte.
|
Ausgangs-Strings Nach Addition Strings einander zugewiesen! |