Da ich von einem C # -Hintergrund kam, war ich mehr oder weniger verwirrt über das seltsam seltsame Verhalten der Rückgabe von Methoden in C ++. Meine Sorge ist jetzt für eine Methode in C ++, die Rückgabe per Referenz ist keine sehr nützliche Technik, dies liegt daran, dass - anders als C # - jede Variable, die innerhalb eines Methodenkörpers deklariert wird, den Gültigkeitsbereich verlässt, sobald das Steuerelement die Methode beendet / p>
Also, in C ++, dies kann nicht einmal kompilieren (aber eine äquivalente Version in C # kann ):
%Vor%Der einzige Zeitpunkt, an dem die Rückgabe als Referenz nützlich ist, ist, wenn Sie eine Referenz auf ein vorhandenes Datenelement in einer Klasse zurückgeben oder eine Referenz auf ein Element innerhalb eines Parameters der Methode zurückgeben. Aber in beiden Fällen gibt es wirklich keine Notwendigkeit, etwas zurückzugeben; da die zurückgegebene Referenz für den Aufrufer der Methode bereits frei verfügbar ist.
Also, meine Schlussfolgerung ist, dass es keine Notwendigkeit gibt, die Rückkehr durch Referenz überhaupt zu verwenden. Habe ich Recht?
Der einzige Zeitpunkt, an dem die Rückgabe über Referenz nützlich ist, ist, wenn Sie eine Referenz auf ein vorhandenes Datenelement in einer Klasse zurückgeben oder eine Referenz auf ein Element innerhalb eines Parameters der Methode zurückgeben.
Losgelöst gesagt, wahr. Die Variable könnte nicht von der Klasse "besessen" werden (wie an ihrer Lebensdauer gebunden): sie könnte für die Klasse durch einen früheren Funktionsaufruf oder einen globalen / Singleton spezifiziert worden sein, der der Klasse bekannt ist, aber kein Teil davon ist, oder Selbst ein neu zugewiesener Bereich im Shared Memory oder im Heap (obwohl die Rückgabe eines Verweises anstelle eines Zeigers andeutet, dass dem Aufrufer keine Eigentumsrechte erteilt werden), muss die Klasse jedoch letztendlich Zugriff auf diese Daten haben.
Aber in beiden Fällen gibt es wirklich keine Notwendigkeit, etwas zurückzugeben; da die zurückgegebene Referenz für den Aufrufer der Methode bereits frei verfügbar ist.
Nein, da Objekte private und geschützte Mitglieder haben können und anderen Klassen oder Funktionen Freundschaften gewähren können, ist es durchaus möglich, dass eine aufgerufene Funktion auf einige Daten zugreifen kann (und daher einen Verweis darauf zurückgibt), auf die der Aufrufer keinen direkten Zugriff hat zu.
Außerdem finden viele Funktionen eine bestimmte Variable, an der sie arbeiten sollen, und geben dann einen Verweis darauf zurück. Wenn der Aufrufer einen separaten Aufruf ausführen musste, um diese Variable erneut zu finden, könnte dies ineffizient sein (ebenso wie im aufrufenden Code).
Also, meine Schlussfolgerung ist, dass es keine Notwendigkeit gibt, die Rückkehr durch Referenz überhaupt zu verwenden. Habe ich Recht?
Nein ... wegen der fehlerhaften Prämisse oben.
Eine andere nicht notwendige, aber bequeme Verwendung der Rückgabe als Referenz wird durch typische Streaming-Funktionen veranschaulicht:
%Vor%Oben, der Verweis auf bedeutet sagen ...
%Vor%... wird als ...
bewertet %Vor%Was alle gut miteinander verbindet. Ähnlich:
%Vor%... funktioniert nicht nur aufgrund der Verkettung für aufeinanderfolgende Eingaben von x und y, sondern auch, weil std :: cin immer noch für die Auswertung in einem booleschen Kontext zur Verfügung steht Operationen funktionierten.
Operationen wie std::vector<>::operator[]
geben Verweise auf Elemente zurück, die durch Dereferenzieren eines Zeigers erhalten wurden (und Hinzufügen von Offsets dazu). Der Zeiger in diesem Fall ist ein private
-Member, das intern zum vector
gehört, und somit nichts, was der Benutzer selbst erhalten hätte, ohne die Abstraktion der Klasse zu unterbrechen.
Es ist korrekt, dass dies nicht funktioniert, um einen Verweis auf etwas zu liefern, das auf dem Stapel zugeordnet ist. Das kann einfach nicht funktionieren.
Die Rückgabe als Referenz kann jedoch immer noch äußerst nützlich sein. Beispielsweise kann der Indexierungsoperator einer Sammlung einen Wert als Referenz zurückgeben, sodass Sie diesem Element in der Sammlung zuweisen können.
Ich wollte nur erwähnen, dass es neben der Rückgabe von Verweisen auf private / geschützte Datenelemente und der Verkettung von Operatoren Techniken in der Template-Metaprogrammierung gibt, die Funktionen verwenden, die durch Verweis auf temporäre Variablen zurückkommen. Dies kann zu einem Leistungszuwachs führen, aber natürlich muss es sorgfältig durchgeführt werden. Die Boost.Proto -Bibliothek ist ein Beispiel für die Verwendung von Expression-Template-Techniken Verweise auf Provisorien, um das Erstellen von Provisorien zu vermeiden. Es tut mir leid, dass ich nicht wirklich ein einfaches Beispiel dafür geben kann ... Ich bin mir nicht sicher, ob ich es selbst verstehe, aber ich wollte nur darauf hinweisen, dass selbst die unlogischsten Dinge in C ++ erlaubt sind, und wenn sie erlaubt sind , jemand wird einen Weg finden, es weise zu benutzen. Und das schließt das Zurückgeben eines Verweises auf ein temporäres ein.
Ich hoffe, dass andere Experten detailliertere Erklärungen abgeben werden. Ich versuche nur ein paar Fälle zu sagen, wenn C / C ++ - Programmierer Referenztypen verwenden.
Der C ++ - Verweistyp ist nur eine syntaktische Erweiterung gegenüber dem alten Zeigertyp von C. In C / C ++ sind alle Parameter und Rückgabewerte Werttyp. Das heißt, Werte werden zu / von Anrufer / Angerufenem kopiert. Anscheinend ist das nicht immer die gewünschte Operation. Wenn also C / C ++ - Programmierer unnötiges Kopieren verhindern wollen, verwenden sie Zeiger oder Referenzen.
Nun .. andere?
Der übliche Zweck der Rückgabe als Referenz ist, dass verkettete Zuweisungen wie folgt vorgenommen werden können:
%Vor%Tags und Links c++