Warum ist "dies" ein Zeiger und keine Referenz?

182

Ich habe die Antworten auf diese Frage C ++ Vor- und Nachteile gelesen und diesen Zweifel beim Lesen der Kommentare bekommen.

Programmierer finden es häufig verwirrend, dass "dies" ein Zeiger, aber keine Referenz ist. Eine weitere Verwirrung ist, warum "Hallo" nicht vom Typ std :: string ist, sondern als char const * (Zeiger) (nach der Konvertierung von Array zu Zeiger) ausgewertet wird - Johannes Schaub - litb 22. Dezember 08 um 1:56

Das zeigt nur, dass es nicht die gleichen Konventionen wie andere (spätere) Sprachen verwendet. - Le Dorfier 22. Dezember 08 um 3:35

Ich würde das "dieses" Ding allerdings als ziemlich triviales Thema bezeichnen. Und hoppla, danke, dass Sie einige Fehler in meinen Beispielen für undefiniertes Verhalten entdeckt haben. :) Obwohl ich nicht verstehe, welche Informationen über die Größe mit irgendetwas im ersten zu tun haben. Ein Zeiger darf einfach nicht außerhalb des zugewiesenen Speichers zeigen - Jalf 22. Dezember 08 um 4:18 Uhr

Ist das ein konstanter Zeiger? - Yesraaj 22. Dezember 08 um 6:35 Uhr

Dies kann konstant sein, wenn die Methode const int getFoo () const ist. <- Im Bereich von getFoo ist "this" konstant und daher schreibgeschützt. Dies verhindert Fehler und bietet dem Aufrufer eine gewisse Garantie dafür, dass sich das Objekt nicht ändert. - Doug T. 22. Dezember 08 um 16:42 Uhr

Sie können "dies" nicht neu zuweisen. Das heißt, Sie können "this = & other;" nicht ausführen, da dies ein Wert ist. Dies ist jedoch vom Typ T *, nicht vom Typ T const. dh es ist ein nicht konstanter Zeiger. Wenn Sie sich in einer const-Methode befinden, ist dies ein Zeiger auf const. T const. aber der Zeiger selbst ist nicht konstant - Johannes Schaub - litb 22. Dezember 08 um 17:53

Stellen Sie sich "this" folgendermaßen vor: #define this (this_ + 0), wobei der Compiler "this_" als Zeiger auf das Objekt erstellt und "this" zu einem Schlüsselwort macht. Sie können "dies" nicht zuweisen, da (this_ + 0) ein r-Wert ist. Natürlich ist das nicht so (es gibt kein solches Makro), aber es kann helfen, es zu verstehen - Johannes Schaub - litb 22. Dezember 08 um 17:55

Meine Frage ist, warum thisein Zeiger keine Referenz ist. Gibt es einen bestimmten Grund, es zu einem Zeiger zu machen?


Einige weitere Argumente, warum thises sinnvoll wäre, eine Referenz zu sein:

  • Beachten Sie Item 1aus More Effective C++ : Verwenden Sie Referenzen, wenn garantiert ist, dass wir ein gültiges Objekt haben, dh kein NULL (meine Interpretation).
  • Darüber hinaus gelten Referenzen als sicherer als Zeiger (da wir den Speicher nicht mit einem streunenden Zeiger vermasseln können).
  • Drittens ist die Syntax für den Zugriff auf referenzen ( .) etwas besser und kürzer als für den Zugriff auf Zeiger ( ->oder (*)).
Naveen
quelle
5
@paulm Was würde dieser "Hack" eigentlich bewirken? Wird nicht thisimmer bewertet true?
iFreilicht
6
@paulm Ich glaube nicht, dass das tatsächlich C ++ ist. Das Aufrufen von Methoden auf einem Nullptr für ein Objekt führt zu undefiniertem Verhalten.
antred
5
@paulm Vielleicht funktioniert es in einigen Fällen, aber stellen Sie sich vor, die Methode wäre virutal. Wie könnte eine V-Tabellen-Suche ohne Objekt durchgeführt werden?
Jason Creighton
3
@paulm Wenn Sie es im Produktionscode gesehen haben, verlassen Sie das Schiff! Das ist UB.
Alice
6
Ich werde das hier einfach lassen ... (aus afxwin2.inl von MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

Antworten:

175

Als sich die Sprache zum ersten Mal weiterentwickelte, gab es in früheren Versionen mit echten Benutzern keine Referenzen, nur Hinweise. Referenzen wurden hinzugefügt, wenn eine Überladung des Bedieners hinzugefügt wurde, da Referenzen erforderlich sind, um konsistent zu funktionieren.

Eine der Anwendungen von thisbesteht darin, dass ein Objekt einen Zeiger auf sich selbst erhält. Wenn es eine Referenz wäre, müssten wir schreiben &this. Wenn wir dagegen einen Zuweisungsoperator schreiben, müssen wir das tun return *this, was einfacher aussehen würde als return this. Wenn Sie also eine leere Tafel hätten, könnten Sie es so oder so argumentieren. C ++ entwickelte sich jedoch allmählich als Reaktion auf das Feedback einer Benutzergemeinschaft (wie die meisten erfolgreichen Dinge). Der Wert der Abwärtskompatibilität überwältigt die geringfügigen Vor- und Nachteile, die sich aus thisder Referenz oder dem Zeiger ergeben.

Daniel Earwicker
quelle
4
Nun, es ist auch oft nützlich, wenn ein Objekt einen Verweis auf sich selbst erhält. Ich würde sagen, das ist eine häufigere Verwendung. Wie auch immer, der Hauptgrund ist, wie Sie sagten, dass Referenzen nicht vorhanden waren, als sie den 'this'-Zeiger erstellten.
Jalf
20
Und wenn dies eine Referenz wäre, wäre es schwierig zu überladen operator &, um irgendetwas Nützliches zu tun. Es müsste eine spezielle Syntax geben, um die Adresse zu erhalten, die nicht durchgehen würde operator &.
Omnifarious
10
@conio - Vielleicht möchten Sie überprüfen, ob Sie das nächste Mal in der Nähe eines C ++ - Compilers sind! :) So etwas wie:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker
14
@ Omnifarious Sie könnten schreiben &reinterpret_cast<char&>(this);, um die reale Adresse für das Überladen zu erhalten operator&(in der Tat ist dies eine Art, was boost::addressoftut).
Johannes Schaub - litb
9
Da es keinen Sinn macht this, null zu sein, scheint mir eine Referenz wirklich passender zu sein.
Ponkadoodle
114

Ein bisschen zu spät zur Party ... Direkt aus dem Maul des Pferdes, hier ist, was Bjarne Stroustrup zu sagen hat (was im Wesentlichen in dem Buch "Design and Evolution of C ++" wiederholt oder daraus entnommen wird):

Warum ist "das" keine Referenz?

Weil "dies" in C ++ eingeführt wurde (wirklich in C mit Klassen), bevor Referenzen hinzugefügt wurden. Außerdem habe ich "dies" gewählt, um der Verwendung von Simula zu folgen, anstatt der (späteren) Smalltalk-Verwendung von "Selbst".

Michael Burr
quelle
2
Ja, ich wäre nett gewesen, um mit anderen Sprachen übereinzustimmen, na ja.
Pilkch