Der this-Zeiger
Inhalt |
[bearbeiten] Syntax
this
|
|||||||||
Der Ausdruck this ist ein prvalue Ausdruck, dessen Wert die Adresse des impliziten Objektparameters (des Objekts, auf dem die implizite Objektmemberfunktion aufgerufen wird) ist. Er kann in folgenden Kontexten auftreten:
|
3) Innerhalb von Standard-Member-Initialisierern.
4) Innerhalb der Capture-Liste eines Lambda-Ausdrucks.
|
(seit C++11) |
[bearbeiten] Erklärung
this kann nur mit der innersten umschließenden Klasse seines Auftretens assoziiert werden, selbst wenn der Auftritt im Kontext ungültig ist.
class Outer { int a[sizeof(*this)]; // Error: not inside a member function unsigned int sz = sizeof(*this); // OK: in default member initializer void f() { int b[sizeof(*this)]; // OK struct Inner { int c[sizeof(*this)]; // Error: not inside a member function of Inner // “this” is not associated with Outer // even if it is inside a member function of Outer }; } };
Der Typ von this in einer Memberfunktion der Klasse X ist X* (Zeiger auf X). Wenn die Memberfunktion mit einer cv-Qualifizierer-Sequenz cv deklariert ist, ist der Typ von this cv X* (Zeiger auf identisch cv-qualifiziertes X). Da Konstruktoren und Destruktoren nicht mit cv-Qualifizierern deklariert werden können, ist der Typ von this in ihnen immer X*, auch beim Konstruieren oder Zerstören eines const-Objekts.
In Klassenvorlagen ist this ein abhängiger Ausdruck, und explizites this-> kann verwendet werden, um einen anderen Ausdruck gezwungen zu machen, davon abzuhängen.
template<typename T> struct B { int var; }; template<typename T> struct D : B<T> { D() { // var = 1; // Error: “var” was not declared in this scope this->var = 1; // OK } };
Während der Konstruktion eines Objekts ist der Wert des Objekts oder eines seiner Unterobjekte, wenn er über ein glvalue zugegriffen wird, das nicht direkt oder indirekt aus dem this-Zeiger des Konstruktors erhalten wurde, nicht spezifiziert. Mit anderen Worten, der this-Zeiger kann in einem Konstruktor nicht gealiast werden.
extern struct D d; struct D { D(int a) : a(a), b(d.a) {} // b(a) or b(this->a) would be correct int a, b; }; D d = D(1); // because b(d.a) did not obtain a through this, d.b is now unspecified
Es ist möglich, delete this; auszuführen, wenn das Programm garantieren kann, dass das Objekt mit new alloziert wurde. Dies macht jedoch jeden Zeiger auf das freigegebene Objekt ungültig, einschließlich des this-Zeigers selbst: Nach der Rückgabe von delete this; kann eine solche Memberfunktion nicht mehr auf ein Member einer Klasse verweisen (da dies eine implizite Dereferenzierung von this beinhaltet) und keine andere Memberfunktion aufgerufen werden.
Dies kann in der Memberfunktion des Referenzzählungszeigers verwendet werden (zum Beispiel std::shared_ptr)(seit C++11), die für die Dekrementierung der Referenzzählung verantwortlich ist, wenn die letzte Referenz auf das verwaltete Objekt den Gültigkeitsbereich verlässt.
class ref { // ... void incRef() { ++mnRef; } void decRef() { if (--mnRef == 0) delete this; } };
[bearbeiten] Schlüsselwörter
[bearbeiten] Beispiel
class T { int x; void foo() { x = 6; // same as this->x = 6; this->x = 5; // explicit use of this-> } void foo() const { // x = 7; // Error: *this is constant } void foo(int x) // parameter x shadows the member with the same name { this->x = x; // unqualified x refers to the parameter // “this->” is required for disambiguation } int y; T(int x) : x(x), // uses parameter x to initialize member x y(this->x) // uses member x to initialize member y {} T& operator=(const T& b) { x = b.x; return *this; // many overloaded operators return *this } };
[bearbeiten] Defect reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 760 | C++98 | wenn this in einer verschachtelten Klasse verwendet wurde, war unklar, ob es mit der verschachtelten oder der umschließenden Klasse assoziiert war |
this assoziiert sich immer mit der innersten verschachtelten Klasse, unabhängig davon, ob es in einer nicht-statischen Memberfunktion vorkommt |
| CWG 2271 | C++98 | this konnte gealiast werden, wenn ein nicht-const Objekt konstruiert wurde |
Aliasing ist auch in diesem Fall verboten |
| CWG 2869 | C++98 | war unklar, ob this in einer statischen Memberfunktion einer nicht-assoziierten Klasse verwendet werden konnte |
wurde klargestellt |