www.mikrocontroller.net

Forum: PC-Programmierung Der This-Zeiger


Autor: Das hohe C(++) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

kann mir jemand die Bedeutung eines This-Zeigers erklären. Werde aus 
meinem Buch echt nicht schlau, was man mit dem Ding anfangen kann.

Danke für die Erkärung

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Angenommen du hast eine Klasse "CFoo", dann kann diese Klasse Attribute 
und Methoden besitzen.

Sagen wir, dass die Klasse wie folgt deklariert ist
class CFoo
{
    int m_Val;

    void SetVal(int Val)
    {
        m_Val = Val;
    }

    int GetVal()
    {
        return m_Val;
    }
};

Nun wird diese Klasse an einer beliebigen Stelle deines Codes beliebig 
oft instanziiert:
CFoo Foo1;
CFoo Foo2;

Nun rufst du die Methode "SetVal" auf.
Foo1.SetVal(666);

Und hier ist die Stelle, wo der this-pointer ins Spiel kommt. Stell dir 
vor, SetVal wäre eine normale C-Funktion. Wäre dem so, so wüsste die 
Funktion nicht, welche Instanz der Klasse CFoo sie ansprechen müsste 
(hier wäre es Foo1). Deshalb wird der Compiler im "Hintergrund" an die 
Funktion "SetVal()" einen Pointer auf die Klasse Foo1 übergeben.
Nun weiß "SetVal()", dass es das Attribut m_Val in der Instanz "Foo1" 
verändern soll.

PS:

Statt
    void SetVal(int Val)
    {
        m_Val = Val;
    }
kannst du demnach auch
    void SetVal(int Val)
    {
        this->m_Val = Val;
    }
schreiben.

Verstanden? Ansonsten muss Karl Heinz ran ;) ;)

Autor: Das hohe C(++) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erst einmal einen riesen Dank für deine ausführliche Antwort. 
Beschäftige mich noch nicht ganz so lange mit der Thematik, daher Gnade, 
wenn ich mit dem Vokabular nicht ganz richtig umgehe. Verstehe deine 
Ausführungen wie folgt:
- Wir haben eine Klasse
- Wir Erstellen die Objekte Foo1 und Foo2

Demanch dürfte doch jetzt im Speicher die beiden Objekte wiedezufinden 
sein mit reserviertem Speicher für die Variablen.
Wenn ich jetzt der Variablen m_Val durch Foo1.SetVal(666); einen Wert 
zuweise,
so ist doch durch Foo1.___(666) eindeutig ein Objekt benannt. Wozu 
gebrauch ich dann noch den this-Zeiger?
Hat er in der Praxis eine große Bedeutung, so dass sein Verständniss 
wichtig ist? Erkenne leider noch nicht richtig seinen Sinn

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hohe C(++) wrote:
> Erst einmal einen riesen Dank für deine ausführliche Antwort.
> Beschäftige mich noch nicht ganz so lange mit der Thematik, daher Gnade,
h> wenn ich mit dem Vokabular nicht ganz richtig umgehe. Verstehe deine
> Ausführungen wie folgt:
> - Wir haben eine Klasse
> - Wir Erstellen die Objekte Foo1 und Foo2

So weit, so gut.

>
> Demanch dürfte doch jetzt im Speicher die beiden Objekte wiedezufinden
> sein mit reserviertem Speicher für die Variablen.

Ist auch richtig.

> Wenn ich jetzt der Variablen m_Val durch Foo1.SetVal(666); einen Wert
> zuweise,
> so ist doch durch Foo1.___(666) eindeutig ein Objekt benannt.

Auch richtig.

> Wozu gebrauch ich dann noch den this-Zeiger?

In dem Fall: gar nicht. Zumindest nicht offensichtlich.
Der Compiler braucht ihn intern um innerhalb der Funktion
auseinanderhalten zu können für welches Objekt denn nun
die Funktion aufgerufen wurde, aber das ist ein Detail,
dass jetzt nicht interessieren muss.


Der this Zeiger ist die C++ Entsprechung für das umgangssprachliche
'Ich' oder 'mein'

this ist die C++ Schreibweise, wie ein Objekt in einer Member-Funktion
von sich selbst sprechen kann.

zb.
2 Klassen: Eine Auto-Klasse und eine Garage. Wenn ein Auto
in die Garage einfährt, muss es sich bei der Garage registrieren.
Umgangssprachlich muss es sagen: Hier bin ich
                                          ***

class Garage
{
  public:
    void Register( Auto* theCar );
};

class Auto
{
  public:
    void ParkIn( Garage* theGarage );
};

void Auto::ParkIn( Garage* theGarage )
{
  // das Auto will in der Garage parken,
  // dazu muss es sich bei der Garage registrieren
  // es 'sagt' zur Garage: Bitte registriere mich
  //                                         ****

  theGarage->Register( this );
}

this ist immer ein Pointer der auf das Objekt zeigt, für
welches eine bestimmte Member Funktion gerade ausgeführt
wird. In vielen Fällen benötigt man den this Pointer nicht,
zb. beim Zugriff auf Member Variablen. Dort ist der this
Pointer implizit

class Auto
{
  public:
    Auto();

  private:
    int AnzahlRaeder;
}

Auto::Auto()
{
  // die Anzahl der Räder für dieses Auto betrage 4
  AnzahlRaeder = 4;

  // hier wurde der this Pointer implizit benutzt
  // man haette genausogut auch schreiben können:
  this->AnzahlRaeder = 4;

  // die Bedeutung wäre identisch
  // Die Anzahl der Räder für das gerade konstruierte
  // Auto Objekt sei 4. Oder aus Sicht dieses Autos:
  // "Ich habe 4 Raeder"
}

aber manchmal, wie zb weiter oben, benötigt man den this
Pointer explizit, damit ein Objekt sich selbst benennen kann.

Ist das jetzt etwas klarer geworden?
this ist einfach nur C++ für 'Ich' oder 'mein' oder 'mich'

Stell dir Objekte wie Personen vor, denen du 'Befehle' geben
kannst. Ein 'Befehl' wird übermittelt, indem man eine Funktion
aufruft. Die Implementierung der Funktion ist dann nichts
anderes als die Ansammlung von Aktionen die dieses Objekt
ausführt, damit es den Befehl befolgen kann. Und zwar
aus Sicht des aktiven Objektes. Zeitweilig muss aber das Objekt
sich selbst ins Spiel bringen, indem es 'ich' oder 'mein' oder
'mich' sagen kann.

Dreh und Angelpunkt der objektorientierten Programmierung ist
die Auffassung, dass Objekte aktive Einheiten sind. In C ist
das noch anders: Da gibt es Strukturen. Diese lungern passiv
im Speicher rum. Weiters gibt es Funktionen, die mit diesen
Strukturen arbeiten. Aber die Strukturen selbst sind einfach
nur passive Daten im Speicher.
Bei der objektorientierten Programmierung bilden Datenstruktur
und Funktionen eine Einheit, eine aktive Einheit, ein Objekt.
Dieses Objekt erledigt eigenständig Befehle, wobei den Befehls-
geber (den Aufrufer einer Funktion) nicht weiter zu interessieren
hat, wie das Objekt einen Befehl ausführt. Aber: Um einen
Befehl auszuführen muss dieses Objekt mit seiner Umwelt (=anderen
Objekten) interagieren. Und genauso wie eine reale Person das
macht, macht das auch ein Objekt: viele Dinge kann es ganz für
sich alleine erledigen. Aber manchmal muss es, genaus wie
auch im richtigen Leben, einen Verweis auf sich selbst bei
anderen Objekten hinterlassen.

Autor: Das hohe C(++) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke an Euch Zwei, die Bedeutung des This-Zeigers ist mir jetzt um 
einiges klarer geworden. Werde es mir zwar noch einmal ganz in Ruhe zu 
Gemüte führen, aber dank Eurer Hilfe ist mir der Sinn schon klar 
geworden. Das Beispiel mit der Garage fand ich sehr verständlich. Es 
können ja zig verschiedenen Autos dort parken wollen. Über den 
This-Zeiger weiß die Garage dann, wer dort wirklich parkt. Stimmt, beim 
Konstruktor muß der zeiger impliziet mitgegeben sein, woher sollte er 
sonst wissen, wem die Daten gehören.

Danke ganz herzlich für Eure Geduld

Andree

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hohe C(++) wrote:
> Danke an Euch Zwei, die Bedeutung des This-Zeigers ist mir jetzt um
> einiges klarer geworden. Werde es mir zwar noch einmal ganz in Ruhe zu
> Gemüte führen, aber dank Eurer Hilfe ist mir der Sinn schon klar
> geworden. Das Beispiel mit der Garage fand ich sehr verständlich. Es
> können ja zig verschiedenen Autos dort parken wollen. Über den
> This-Zeiger weiß die Garage dann, wer dort wirklich parkt. Stimmt, beim
> Konstruktor muß der zeiger impliziet mitgegeben sein, woher sollte er
> sonst wissen, wem die Daten gehören.
>
> Danke ganz herzlich für Eure Geduld
>
> Andree

Nicht ganz. Ist vielleicht etwas untergegangen in Karl-Heinz Post, aber 
den this pointer solltest du erstmal als etwas "Compiler-internes" 
ansehen. Etwas, was der Compiler benötigt um deinen Code zu kompilieren.

Dieser this-Pointer wird (ohne, dass du es siehst) bei jedem 
Methodenaufruf (außer statische Methoden, aber das ist jetzt erstmal 
wurscht) an die aufgerufene Methode übergeben.

Im Falle von
Foo1.SetVal(123);

wird also die "Funktion" SetVal aufgerufen und ihr "im Hintergrund" ein 
Pointer auf Foo1 übergeben. Dieser Pointer wird dann innerhalb der 
Methode "SetVal" zu dem this-Pointer.

Jetzt weiß SetVal() auf welche Instanz der Klasse CFoo er sich beziehen 
muss.

PS: Das ist wieder so ein Thema, dass man relativ schlecht erklären 
kann. (Oder geht es nur mir so ;)). Wenn man sich Gedanken darüber 
macht, wie der Compiler mit Methoden und Attributen umgeht, kommt man 
quasi automatisch auf die Idee des this-Pointers.. Das Problem ist nur, 
sich über den Compiler Gedanken zu machen, setzt wiederum eine gewisse 
Grundkenntnis voraus :-/

Autor: ehm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Über den Compiler könnte ich den this Pointer auch nicht wirklich 
verständlich erklären. Allerdings habe ich ein weiteres praktisches 
Beispiel, bei dem ich vor kurzem den this Pointer genutzt habe: Das 
Überladen des = Operators mit anschliessender Verkettung:
class CKiste
{
     private:
     float laenge, breite, hoehe;
     public:
     CKiste& operator =(CKiste&);
     ...
};

CKiste& CKiste::operator =(CKiste& _k)
{
  laenge = _k.laenge ;
  breite = _k.breite;
  hoehe = _k.hoehe;
  return(*this);
}

int main()
{
        CKiste k1(5,1,2), k2(3,4,8), k3(6,9,7);
    
  k1 = k2 = k3;
        //Das kann man nur schreiben, da "die Operation" k2 = k3 einen              
        //Wert, also in diesem Fall das neue k2 als Referenz zurückgibt.
 
        return(0);
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.