Wo ist der "this" - Zeiger im Speicher des Rechners gespeichert?
Wo genau ist der "this" - Zeiger, die im Speicher abgespeichert? Ist reserviert auf dem stack in den heap oder im Daten-segment?
#include <iostream>
using namespace std;
class ClassA
{
int a, b;
public:
void add()
{
a = 10;
b = 20;
cout << a << b << endl;
}
};
int main()
{
ClassA obj;
obj.add();
return 0;
}
Im obigen code bin ich dem Aufruf der member-Funktion add()
- und das Empfänger-Objekt übergeben wird implizit als die "this" - Zeiger. Wo ist this
im Speicher abgelegt?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Anderen Antworten haben einen sehr guten job gemacht zu erklären, wie eine typische compiler implementiert
this
(indem Sie es als einen impliziten ersten parameter der Funktion).Ich denke, es ist auch nützlich, um zu sehen, was die C++ - ISO-spec explizit dazu schreibt. Entsprechend der C++ - 03 ISO spec, §9.3.2/1:
Es ist wichtig zu beachten, dass
this
ist nicht eine variable - es ist ein Ausdruck, viel in der gleichen Weise, dass die expression1 + 2 * 3
ist ein Ausdruck. Der Wert dieses Ausdrucks zulässig ist, gespeichert werden, so ziemlich überall. Der compiler könnte legte es auf den Stapel und übergeben Sie es als einen impliziten parameter an eine Funktion, oder es könnte steckte es in ein register, und möglicherweise könnte man es im heap oder im Daten-segment. Die C++ - Spezifikation absichtlich verleiht der Umsetzung eine gewisse Flexibilität hier.Ich denke, dass die "Sprache-Anwalt" Antwort "das ist völlig Implementierung-definiert, und darüber hinaus
this
ist technisch kein Zeiger, sondern ein Ausdruck, dessen Wert einen Zeiger."Hoffe, das hilft!
Der einfachste Weg ist, zu denken
this
als eine versteckte zusätzliche argument, das immer automatisch übergeben.So, eine fiktive Methode wie:
ist eigentlich mehr unter der Haube:
einen Aufruf wie:
wird zu etwas, wie:
Beachten Sie, dass die obige transformation wird vereinfacht, hoffentlich um meinen Standpunkt ein wenig klarer. Keine Notwendigkeit, füllen die Kommentare mit "whaaa, wo ist das marshalling für die Methode überladen, nicht wahr?"-Art Einwand, bitte. 🙂
Verwandelt sich die Frage in "wo sind die Argumente gespeichert werden?", und die Antwort ist natürlich "it depends". 🙂
Ist es oft auf dem Stapel, aber es werden könnten, in einem Register zu, oder jeder andere Mechanismus, den der compiler betrachtet ist gut für die Ziel-Architektur.
ecx
zum speichern des this-Zeiger.ecx
.__thiscall
immer verwendetecx
übergeben werden, diethis
Zeiger auf eine member-Funktion (obwohl der compiler kann mische es etwa innerhalb der Funktion, wenn es entscheidet, dass die register für etwas anderes). Siehe hier.this
ist in der Regel bestanden, als eine versteckte argument der Methode (der einzige Unterschied in den verschiedenen Aufrufkonventionen ist wie).Wenn Sie rufen:
Compiler generiert den folgenden code:
Wobei der erste parameter ist eigentlich der Zeiger auf
this
.Let ' s überprüfen Sie den folgenden code:
Mithilfe
__stdcall
ich gezwungen, den compiler zu übergeben, alle Parameter über den stack. Wenn Sie dann starten Sie den debugger und prüfen Sie die assembly-code, finden Sie etwas wie die folgenden:Wie Sie sehen, ist der parameter der Methode übergeben wird, durch den Stapel, dann die Adresse von myClass ist geladen und die register " eax " und wieder auf den stack geschoben. In anderen Worten,
this
wird behandelt wie eine reguläre parameter der Methode.this
ist immer übergeben als impliziten ersten parameter der Funktion. Dies ist, wie die meisten Implementierungen machenthis
Arbeit, aber es ist keine Voraussetzung, dass dies tatsächlich eintreten muss. Andere Implementierungen sind möglich.this
ist ein rvalue (Sie können nicht Ihre Adresse), so ist es nicht(unbedingt) zu besetzen Speicher. Je nach compiler
und die Ziel-Architektur wird es oft in einem register: i0
auf einem Sparc -, ECX-mit MSVC auf Intel, etc. Wenn der Optimierer ist
aktiv, kann es sogar zu bewegen. (Ich habe es in verschiedenen
Register mit MSVC).
this
verhält sich meist wie eine Funktion als argument, und als solche wird auf dem stack gespeichert werden oder - wenn die binären Aufrufkonventionen von der Architektur ermöglichen es, dass - in einem register.this
ist nicht gespeichert auf einer wohldefinierten Lage! Das Objekt, das er verweist ist irgendwo gespeichert, und hat eine gut definierte Adresse, sondern die Adresse selbst nicht über eine bestimmte Adresse. Es ist mitgeteilt, um in das Programm. Nicht nur, dass, aber es kann viele Kopien der Zeiger.In der folgenden imaginären
init
Funktion, das Objekt registriert sich selbst zu erhalten, Ereignisse und timer-callbacks (mit imaginären Quelle-Objekte). Also, nach der Registrierung, gibt es zwei zusätzliche Kopien vonthis
:Ich eine Funktion die Aktivierung der Kette, es werden auch mehrere Kopien der this-Zeiger. Nehmen wir an, wir haben ein Objekt
obj
und rufen Sie seinefoo
Funktion. Diese Funktion ruft die gleiche Objektbar
Funktion, undbar
ruft eine andere Funktion aufgerufenupdate
. Jede Funktion Aktivierung Ebene hat diethis
Zeiger. Es ist gespeichert in einer Maschine register, oder eine Speicherstelle im stack-frame der Funktion Aktivierung.