C++ Kurs

this-Zeiger

Die Themen:

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 wir uns einmal das nachfolgende Beispiel an. Dort wird eine minimale Klasse definiert, die nur eine einzige Memberfunktion Anything(...) enthält.

PgmHeader
#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 und anschließend werden die Adressen beider Objekte ausgegeben.

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

ProgrammausgabeAdr. 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 benötigt, 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 der Fensterfarbe 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. Wird 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 des Fensters auslesen. Wird die Funktion nicht aus einer Window Memberfunktion heraus aufgerufen, so wird für den Window-Zeiger ein nullptr übergeben. In diesem Fall wird eine Standardfarbe für die Ausgabe verwendet. Damit nun bei einem allgemeinen Aufruf nicht immer der nullptr angegeben werden muss, wird dieser Parameter standardmäßig mit dem nullptr 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 Fensterfarbe 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.

PgmHeader
// 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 = nullptr);

// 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 == nullptr)
   {
      // 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()!");
}
ProgrammausgabeVordergrund: 0x112233, Hintergrund: 0x0000ff
Text ist : Fenstermeldung!
Vordergrund: 0x000000, Hintergrund: 0xffffff
Text ist : Meldung von main()!

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