C++ Kurs

this-Zeiger

Die Themen:

this-Zeiger
Beispiel

this-Zeiger

Jede nicht-statische Memberfunktion erhält als versteckten Parameter einen Zeiger auf das Objekt, in dessen Kontext sie aufgerufen wurde. Dieser Zeiger wird this-Zeiger genannt. Er ist immer vom Typ 'Zeiger auf eigene Klasse'.

Sehen Sie sich einmal das nachfolgende Beispiel an. Dort wird eine minimale Klasse definiert, die nur aus einer einzigen Memberfunktion Anything(...) besteht.


#include <iostream>
using std::cout;
using std::endl;

// Klassendefinition
class Any
{
 public:
   void Anything();
};
// Defínition der einzigen Memberfunktion
void Any::Anything()
{
   // Inhalt des this-Zeigers ausgeben
   cout << "this=" << this << endl;
}

// main() Funktion
int main()
{
   // 2 Objekte definieren
   Any obj1, obj2;
   cout << std::hex;
   // Adressen der Objekte ausgeben
   cout << "Adr. obj1=" << &obj1 << endl;
   cout << "Adr. obj2=" << &obj2 << endl;
   // this-Zeiger der Objekte ausgeben
   cout << "this-Zeiger ausgeben:\n";
   obj1.Anything();
   obj2.Anything();
}

In main() werden zwei Objekte dieser Klasse definiert. Anschließend werden die Adressen  beider Objekte ausgegeben, was letztendlich nichts anderes bedeutet, wie die Ausgabe der Zeiger auf diese Objekte.

Danach rufen beide Objekte ihre Memberfunktion Anything() auf. In dieser Memberfunktion wird dann der Inhalt des this-Zeigers ausgegeben. Und da dieser Zeiger laut obiger Aussage auf das aufrufende Objekt zeigt, werden hier die gleichen Adressen wie vorher in main()  Funktion ausgegeben.

Adr. obj1=0016FE57
Adr. obj2=0016FE4B
this-Zeiger ausgeben:
this=0016FE57
this=0016FE4B

Vielleicht fragen Sie sich jetzt, für wofür dieser Zeiger eigentlich eingesetzt wird? Nun, dieser Zeiger wird immer dann verwendet, wenn ein Zeiger oder eine Referenz auf das aktuelle Objekt innerhalb einer Memberfunktion benötigt wird. Aber sehen wir uns dies am Besten anhand des Beispiels an.

Beispiel

Beispiel:

Es soll eine Funktion (keine Memberfunktion) zur Ausgabe einer Meldung auf dem Bildschirm geschrieben werden. Die Ausgabe soll dabei mit einer bestimmten Vorder- und Hintergrundfarbe erfolgen. Die Funktion erhält als Parameter zunächst den auszugebenden Text. Die Bestimmung der Farbe für die Ausgabe erfolgt nach folgendem Verfahren:

  • Wird die Funktion aus einer Memberfunktion der ebenfalls im Beispiel definierten Fensterklasse Window heraus aufgerufen, so wird die Meldung in den Fensterfarben dargestellt.
  • Wird die Funktion anderweitig, z.B. aus main() heraus, aufgerufen, wird eine Standardfarbe für die Ausgabe verwendet.

Damit die Funktion nun feststellen kann, von wo aus sie aufgerufen wurde, erhält sie als zweiten Parameter einen Window-Zeiger. Wenn die Funktion aus einer Window Memberfunktion heraus aufgerufen wird, so übergibt die Memberfunktion an die Ausgabefunktion einen Zeiger auf das aktuelle Objekt, und dies ist der this-Zeiger. Über diesen Zeiger kann die Ausgabefunktion dann die aktuelle Vorder- und Hintergrundfarbe auslesen. Wird die Funktion nicht aus einer Window Memberfunktion heraus aufgerufen, so wird für den Window-Zeiger ein NULL-Zeiger übergeben. In diesem Fall wird eine Standardfarbe für die Ausgabe verwendet. Damit nun bei einem allgemeinen Aufruf nicht immer der NULL-Zeiger angegeben werden muss, wird dieser Parameter standardmäßig mit NULL vorbelegt (Default-Parameter).

In main() wird zunächst ein Window Objekt definiert und dessen Memberfunktion DoAnything() aufgerufen, die dann wiederum die Ausgabefunktion DisplayMessage(...) aufruft. Diese Ausgabefunktion erhält nun (außer dem auszugebenden Text) als Parameter den Zeiger auf das aktuelle Objekt (this-Zeiger), damit die Funktion dessen Fensterfarben auslesen kann. Im Anschluss wird in main() noch eine weitere Meldung mittels DisplayMessage(...) ausgegeben, wobei der letzte Parameter (Window-Zeiger) jetzt beim Aufruf entfällt (Default-Parameter). Damit wird für die Ausgabe die definierte Standardfarbe verwendet.

Vordergrund: 0x112233, Hintergrund: 0x0000ff
Text ist : Fenstermeldung!
Vordergrund: 0x000000, Hintergrund: 0xffffff
Text ist : Meldung von main()!


// Beispiel zum this-Zeiger

// Zuerst Dateien einbinden

#include <iostream>
#include <iomanip>

using std::cout;
using std::endl;

// Vorwärtsdeklaration wegen nachfolgender
// Deklaration der Funktion DisplayMessage(...)

class Window;

// Funktionsdeklaration
void DisplayMessage(const char* const pMsg, Window *pParent = NULL);

// Klassendefinition
class Window
{
   // Fensterfarben
   unsigned long foreColor, backColor;
 public:
   // ctor
   Window(unsigned long fc, unsigned long bc);
   // Auslesen der Fensterfarben
   void GetColor(unsigned long &fc, unsigned long &bc);
   // Beliebige Memberfunktion
   void DoAnything();
};
// Definition der Memberfunktionen
// Konstruktor, setzt die Fensterfarben

Window::Window(unsigned long fc, unsigned long bc)
{
   foreColor = fc;
   backColor = bc;
}
// Fensterfarben zurückliefern
void Window::GetColor(unsigned long &fc, unsigned long &bc)
{
   fc = foreColor;
   bc = backColor;
}
// Ausgabe einer Meldung
void Window::DoAnything()
{
   DisplayMessage("Fenstermeldung!",this);
}

// Funktion zur Ausgabe der Meldung
void DisplayMessage(const char* const pMsg,Window *pParent)
{
   unsigned long fc, bc;
   // Falls Aufruf der Funktion nicht von einem Fenster aus
   if (pParent == NULL)
   {
      // Standardfarben für Ausgabe verwenden
      fc = 0UL;
      bc = 0xFFFFFFUL;
   }
   else
   {
      // sonst Fensterfarben verwenden
      pParent->GetColor(fc, bc);
   }
   // Meldung ausgeben
   cout << std::hex << std::setfill('0');
   cout << "Vordergrund: 0x" << std::setw(6) << fc;
   cout << ", Hintergrund: 0x" << std::setw(6) << bc << endl;
   cout << std::dec << std::setfill(' ');
   cout << "Text ist : " << pMsg << endl;
}

// main() Funktion
int main()
{
   // Fensterobjekt erstellen
   Window myWin(0x112233UL,0x0000FFUL);
   // Memberfunktion des Fensters aufrufen
   myWin.DoAnything();
   // Meldung ausgeben
   DisplayMessage("Meldung von main()!");
}

Auf eine Übung können wir hier getrost verzichten, da uns dieser Zeiger in den nachfolgenden Lektionen noch öfters begegnen wird.