Ich bin mir sicher, dass dies ein Betrug ist, aber es ist natürlich nicht durchsuchbar. Nicht zum ersten Mal wünschte ich mir, dieser Zeiger würde Selbst heißen!
5
Nicht nur das, ich wünschte, es wäre eine Referenz.
Rlbond
2
Gleich. : | Hier ist übrigens der
Grund
11
Diese Methode funktioniert offensichtlich nicht, wenn die Person die Antwort nicht kennt.
Normalerweise müssen Sie nicht, this-> ist impliziert.
Manchmal gibt es eine Namensmehrdeutigkeit, mit der Klassenmitglieder und lokale Variablen eindeutig unterschieden werden können. Hier ist jedoch ein ganz anderer Fallthis-> ausdrücklich erforderlich ist.
Betrachten Sie den folgenden Code:
template<class T>struct A {int i;};template<class T>struct B : A<T>{int foo(){returnthis->i;}};int main(){
B<int> b;
b.foo();}
Wenn Sie dies weglassen this->, weiß der Compiler nicht, wie er zu behandeln ist i, da er möglicherweise in allen Instanziierungen von vorhanden ist oder nicht A. Um es zu sagen, iist das in der Tat ein Mitglied von A<T>, für jedenT das this->Präfix erforderlich.
Hinweis: Es ist weiterhin möglich, das this->Präfix wegzulassen, indem Sie Folgendes verwenden:
template<class T>struct B : A<T>{using A<T>::i;// explicitly refer to a variable in the base classint foo(){return i;// i is now known to exist}};
Dies ist ein besonders schlimmer Fall. Ich bin schon einmal davon gebissen worden.
Jason Baker
5
Dies mag eine dumme Frage sein, aber ich verstehe nicht, warum ies in nicht existiert A. Könnte ich ein Beispiel bekommen?
Cam Jackson
1
@CamJackson Ich habe den Code in Visual Studio ausprobiert. Die Ergebnisse sind die gleichen, egal ob "this->" existiert oder nicht. Irgendeine Idee?
Peng Zhang
8
@ CamJackson: Man kann Klassen auf Typ spezialisieren:template<> struct A<float> { float x; };
Macke
31
Wenn Sie eine lokale Variable in einer Methode mit demselben Namen wie ein vorhandenes Mitglied deklarieren, müssen Sie this-> var verwenden, um auf das Klassenmitglied anstelle der lokalen Variablen zuzugreifen.
#include<iostream>usingnamespace std;class A
{public:int a;void f(){
a =4;int a =5;
cout << a << endl;
cout <<this->a << endl;}};int main(){
A a;
a.f();}
Beachten Sie in Ihrem letzten Fall, dass Sie eine Nichtmitgliedsfunktion constfür eine temporäre Funktion aufrufen können ( Type(rhs).swap(*this);ist legal und korrekt), eine temporäre Funktion jedoch nicht an einen nicht konstanten Referenzparameter binden kann (Compiler lehnt dies swap(Type(rhs));ebenfalls ab this->swap(Type(rhs));)
Ben Voigt
5
Es gibt wenige Fälle, in denen die Verwendung thisverwendet werden muss , und es gibt andere Fälle, in denen die Verwendung des thisZeigers eine Möglichkeit ist, ein Problem zu lösen.
1) Verfügbare Alternativen : Zum Auflösen von Mehrdeutigkeiten zwischen lokalen Variablen und Klassenmitgliedern, wie in @ASk dargestellt .
2) Keine Alternative: Um einen Zeiger oder Verweis thisvon einer Mitgliedsfunktion zurückzugeben. Dies wird häufig getan (und sollte getan werden) , wenn eine Überlastung operator+, operator-, operator=, etc:
Dies ermöglicht eine Redewendung, die als " Methodenverkettung " bezeichnet wird und bei der Sie mehrere Operationen an einem Objekt in einer Codezeile ausführen. Sowie:
Einige halten dies für eine Abscheulichkeit, andere für einen Greuel. Zähle mich in der letzteren Gruppe.
3) Keine Alternative: Zum Auflösen von Namen in abhängigen Typen. Dies tritt auf, wenn Vorlagen verwendet werden, wie in diesem Beispiel:
#include<iostream>template<typenameVal>classValHolder{private:Val mVal;public:ValHolder(constVal& val):
mVal (val){}Val&GetVal(){return mVal;}};template<typenameVal>classValProcessor:publicValHolder<Val>{public:ValProcessor(constVal& val):ValHolder<Val>(val){}ValComputeValue(){// int ret = 2 * GetVal(); // ERROR: No member 'GetVal'int ret =4*this->GetVal();// OK -- this tells compiler to examine dependant type (ValHolder)return ret;}};int main(){ValProcessor<int> proc (42);constint val = proc.ComputeValue();
std::cout << val <<"\n";}
4) Verfügbare Alternativen: Als Teil des Codierungsstils, um zu dokumentieren, welche Variablen im Gegensatz zu lokalen Variablen Mitgliedsvariablen sind. Ich bevorzuge ein anderes Namensschema, bei dem Mitgliedsvariablen niemals den gleichen Namen wie Einheimische haben können. Derzeit benutze ich mNamefür Mitglieder und namefür Einheimische.
Sie müssen dies-> nur verwenden, wenn Sie ein Symbol mit demselben Namen in zwei möglichen Namespaces haben. Nehmen Sie zum Beispiel:
class A {public:void setMyVar(int);void doStuff();private:int myVar;}void A::setMyVar(int myVar){this->myVar = myVar;// <- Interesting point in the code}void A::doStuff(){int myVar =::calculateSomething();this->myVar = myVar;// <- Interesting point in the code}
An den interessanten Stellen im Code bezieht sich die Bezugnahme auf myVar auf die lokale (Parameter oder Variable) myVar. Um auf das Klassenmitglied zuzugreifen, das auch myVar genannt wird, müssen Sie explizit "this->" verwenden.
Dies ist die einzige Verwendung this->, die trivial zu vermeiden ist (geben Sie der lokalen Variablen einfach einen anderen Namen). Alle wirklich interessanten Verwendungen von thiswerden in dieser Antwort nicht einmal erwähnt.
cmaster
4
Die andere Verwendung dafür (wie ich dachte, als ich die Zusammenfassung und die Hälfte der Frage gelesen habe ...), die (schlechte) Namensdisambiguierung in anderen Antworten außer Acht lässt, ist, wenn Sie das aktuelle Objekt umwandeln möchten, es in ein Funktionsobjekt zu binden oder verwenden Sie es mit einem Zeiger auf ein Mitglied.
Casts
voidFoo::bar(){
misc_nonconst_stuff();constFoo* const_this =this;
const_this->bar();// calls const versiondynamic_cast<Bar*>(this)->bar();// calls specific virtual function in case of multi-inheritance}voidFoo::bar()const{}
Nein, Sie nicht brauchen , es können Sie verwenden es. Sie können auch einen anderen Namen für das Funktionsargument verwenden, was den Vorteil hat, dass nicht zwei Entitäten mit demselben Namen vorhanden sind.
cmaster
3
Der Hauptzweck (oder ich kann sagen, der einzige) des thisZeigers besteht darin, dass er auf das Objekt zeigt, mit dem eine Elementfunktion aufgerufen wird.
Basierend auf diesem Zweck können wir einige Fälle haben, in denen nur die Verwendung eines thisZeigers das Problem lösen kann.
Zum Beispiel müssen wir das aufrufende Objekt in einer Mitgliedsfunktion mit Argument zurückgeben, das dasselbe Klassenobjekt ist:
class human {...
human & human::compare(human & h){if(condition)return h;// argument objectelsereturn*this;// invoking object}};
Oder Sie können lengthveränderlich machen oder es sogar in eine verschachtelte Struktur einfügen. Konstanz wegzuwerfen ist fast nie eine gute Idee.
Richard J. Ross III
3
Bitte nicht. Wenn das Mitglied von den constMitgliedsfunktionen geändert werden soll, sollte es das sein mutable. Andernfalls machen Sie das Leben für Sie und andere Betreuer komplizierter.
research.att.com/~bs/
jetzt so ausstroustrup.com
. Neuer Link: stroustrup.com/bs_faq2.html#thisAntworten:
Normalerweise müssen Sie nicht,
this->
ist impliziert.Manchmal gibt es eine Namensmehrdeutigkeit, mit der Klassenmitglieder und lokale Variablen eindeutig unterschieden werden können. Hier ist jedoch ein ganz anderer Fall
this->
ausdrücklich erforderlich ist.Betrachten Sie den folgenden Code:
Wenn Sie dies weglassen
this->
, weiß der Compiler nicht, wie er zu behandeln isti
, da er möglicherweise in allen Instanziierungen von vorhanden ist oder nichtA
. Um es zu sagen,i
ist das in der Tat ein Mitglied vonA<T>
, für jedenT
dasthis->
Präfix erforderlich.Hinweis: Es ist weiterhin möglich, das
this->
Präfix wegzulassen, indem Sie Folgendes verwenden:quelle
i
es in nicht existiertA
. Könnte ich ein Beispiel bekommen?template<> struct A<float> { float x; };
Wenn Sie eine lokale Variable in einer Methode mit demselben Namen wie ein vorhandenes Mitglied deklarieren, müssen Sie this-> var verwenden, um auf das Klassenmitglied anstelle der lokalen Variablen zuzugreifen.
Drucke:
5
4
quelle
Es gibt mehrere Gründe, warum Sie den
this
Zeiger möglicherweise explizit verwenden müssen.quelle
Obwohl ich es normalerweise nicht besonders mag, habe ich gesehen, dass andere dies benutzen -> nur um Hilfe von Intellisense zu bekommen!
quelle
Einige Codierungsstandards verwenden Ansatz (2), da sie behaupten, dass er den Code leichter lesbar macht.
Beispiel:
Angenommen, MyClass hat eine Mitgliedsvariable namens 'count'
quelle
Ein anderer Fall ist das Aufrufen von Operatoren. ZB statt
Sie können sagen
Welches könnte besser lesbar sein. Ein weiteres Beispiel ist das Kopieren und Austauschen:
Ich weiß nicht, warum es nicht geschrieben ist,
swap(temp)
aber das scheint üblich zu sein.quelle
const
für eine temporäre Funktion aufrufen können (Type(rhs).swap(*this);
ist legal und korrekt), eine temporäre Funktion jedoch nicht an einen nicht konstanten Referenzparameter binden kann (Compiler lehnt diesswap(Type(rhs));
ebenfalls abthis->swap(Type(rhs));
)Es gibt wenige Fälle, in denen die Verwendung
this
verwendet werden muss , und es gibt andere Fälle, in denen die Verwendung desthis
Zeigers eine Möglichkeit ist, ein Problem zu lösen.1) Verfügbare Alternativen : Zum Auflösen von Mehrdeutigkeiten zwischen lokalen Variablen und Klassenmitgliedern, wie in @ASk dargestellt .
2) Keine Alternative: Um einen Zeiger oder Verweis
this
von einer Mitgliedsfunktion zurückzugeben. Dies wird häufig getan (und sollte getan werden) , wenn eine Überlastungoperator+
,operator-
,operator=
, etc:Dies ermöglicht eine Redewendung, die als " Methodenverkettung " bezeichnet wird und bei der Sie mehrere Operationen an einem Objekt in einer Codezeile ausführen. Sowie:
Einige halten dies für eine Abscheulichkeit, andere für einen Greuel. Zähle mich in der letzteren Gruppe.
3) Keine Alternative: Zum Auflösen von Namen in abhängigen Typen. Dies tritt auf, wenn Vorlagen verwendet werden, wie in diesem Beispiel:
4) Verfügbare Alternativen: Als Teil des Codierungsstils, um zu dokumentieren, welche Variablen im Gegensatz zu lokalen Variablen Mitgliedsvariablen sind. Ich bevorzuge ein anderes Namensschema, bei dem Mitgliedsvariablen niemals den gleichen Namen wie Einheimische haben können. Derzeit benutze ich
mName
für Mitglieder undname
für Einheimische.quelle
Sie müssen dies-> nur verwenden, wenn Sie ein Symbol mit demselben Namen in zwei möglichen Namespaces haben. Nehmen Sie zum Beispiel:
An den interessanten Stellen im Code bezieht sich die Bezugnahme auf myVar auf die lokale (Parameter oder Variable) myVar. Um auf das Klassenmitglied zuzugreifen, das auch myVar genannt wird, müssen Sie explizit "this->" verwenden.
quelle
this->
, die trivial zu vermeiden ist (geben Sie der lokalen Variablen einfach einen anderen Namen). Alle wirklich interessanten Verwendungen vonthis
werden in dieser Antwort nicht einmal erwähnt.Die andere Verwendung dafür (wie ich dachte, als ich die Zusammenfassung und die Hälfte der Frage gelesen habe ...), die (schlechte) Namensdisambiguierung in anderen Antworten außer Acht lässt, ist, wenn Sie das aktuelle Objekt umwandeln möchten, es in ein Funktionsobjekt zu binden oder verwenden Sie es mit einem Zeiger auf ein Mitglied.
Casts
Bindung
ptr-to-member
Ich hoffe, es hilft, andere Verwendungszwecke als nur dieses-> Mitglied aufzuzeigen.
quelle
Sie müssen verwenden
this
, um zwischen Parametern / lokalen Variablen und Mitgliedsvariablen zu unterscheiden.quelle
Der Hauptzweck (oder ich kann sagen, der einzige) des
this
Zeigers besteht darin, dass er auf das Objekt zeigt, mit dem eine Elementfunktion aufgerufen wird.Basierend auf diesem Zweck können wir einige Fälle haben, in denen nur die Verwendung eines
this
Zeigers das Problem lösen kann.Zum Beispiel müssen wir das aufrufende Objekt in einer Mitgliedsfunktion mit Argument zurückgeben, das dasselbe Klassenobjekt ist:
quelle
Ich fand einen weiteren interessanten Fall der expliziten Verwendung des Zeigers "this" im Effective C ++ - Buch.
Angenommen, Sie haben eine const-Funktion wie
Sie möchten nicht die Länge des Strings für jeden Aufruf berechnen, daher möchten Sie ihn zwischenspeichern, indem Sie so etwas tun
Dies wird jedoch nicht kompiliert - Sie ändern das Objekt in einer const-Funktion.
Der Trick zu lösen dies erfordert Gießen dies zu einem nicht-const diese :
Dann können Sie oben tun
quelle
length
veränderlich machen oder es sogar in eine verschachtelte Struktur einfügen. Konstanz wegzuwerfen ist fast nie eine gute Idee.const
Mitgliedsfunktionen geändert werden soll, sollte es das seinmutable
. Andernfalls machen Sie das Leben für Sie und andere Betreuer komplizierter.