Wofür sind Referenzen und was machen sie?
-
Wie ich bereits sagte - Referenzen sind auch Zeiger.
-
Ja aber dann Zeiger auf einen Zeiger und konstant, oder?
-
CarstenJ schrieb:
Hast du jetzt meinen Beitrag nicht verstanden, oder ich deine vorherige Frage nicht?!
Das hilft mir jetzt auch nicht weiter. Naja, wenn du dir die Tutorials mal durchgelesen hast, sollte es eigentlich klarer werden und beachte meinen Beitrag einfach nicht.
Ich deinen Beitrag nicht!
Was ich jetzt genau nicht verstehe ist:Was die genau machen!
-
interpreter schrieb:
Strogij schrieb:
Und noch was: die Referenzen belegen keinen eigenen Speicher, die Zeiger schon. Dafür können die Referenzen aber auch nicht 'springen'.
Doch können Sie auch! oder ich weiss nicht was du meinst!
C/C++ Code:
int a = 10;
int b = 20;int& ref = a;
cout << ref << endl;ref = b;
cout << ref << endl;Strogij hatte mit seiner Aussage, dass Referenzen nicht "springen" können schon recht. in deinem Codebeispiel lässt du eben NICHT ref auf b zeigen, sondern kopierst den Wert von b nach a.
Ja stimmt! Ich habe da was verwechselt! Referenzen werden bei der Deklaration definiert und können nicht mehr woanders hinzeigen!
-
Strogij schrieb:
Ja aber dann Zeiger auf einen Zeiger und konstant, oder?
Nein, es sind Zeiger.
int i; int &ref = i;
ref zeigt jetzt auf i, enthält also die Adresse von i. Es ist genau wie bei Zeigern. Der einzige Unterschied ist, dass du die Referenz nicht neu zuweisen kannst. Sie wird für den Rest ihres Lebens auf i zeigen.
Klar kannst du dir es einfach als anderen Namen vorstellen, aber es ist technisch ein Zeiger. Deshalb verbraucht die Referenz genauso wie ein Zeiger 4Bytes Speicherplatz auf einem 32-Bit System.
-
Danke dir, der Grund für meine Aussage waren wohl die Referenzen bei PHP, aber das ist ja ein ganz anderer Witz.
PS: Ich hoffe der Autor versteht es jetzt...
-
@Optimizer
Könntest du deine Aussage bitte mal belegen? Ich sehe das nämlich etwas anders. Und zwar so:
Referenzen werden häufig (keinesfalls immer) über Zeiger implementiert, und
belegen dann auch genausoviel Speicher wie ein Zeiger.
Der Standard schreibt dies aber nicht vor.Desweiteren benötigen Referenzen nicht zwangsläufig Speicher.
Vielmehr brauchen sie selbigen nur in speziellen Situationen, z.B. als Funktionsparameter oder Rückgabewerte.
Lokale (gloable) Referenzen müssen aber keinen Speicher belegen, da Refernzen nur Aliasnamen für andere Objekte sind. Sind sind selbst aber keine Objekte mit einer eindeutigen Identität, sie sind nicht direkt adressierbar und müssen demzufolge auch keinen eigenen Speicherbereich besitzen.
-
HumeSikkins schrieb:
@Optimizer
Könntest du deine Aussage bitte mal belegen? Ich sehe das nämlich etwas anders. Und zwar so:
Referenzen werden häufig (keinesfalls immer) über Zeiger implementiert, und
belegen dann auch genausoviel Speicher wie ein Zeiger.
Der Standard schreibt dies aber nicht vor.Desweiteren benötigen Referenzen nicht zwangsläufig Speicher.
Vielmehr brauchen sie selbigen nur in speziellen Situationen, z.B. als Funktionsparameter oder Rückgabewerte.
Lokale (gloable) Referenzen müssen aber keinen Speicher belegen, da Refernzen nur Aliasnamen für andere Objekte sind. Sind sind selbst aber keine Objekte mit einer eindeutigen Identität, sie sind nicht direkt adressierbar und müssen demzufolge auch keinen eigenen Speicherbereich besitzen.Wenn ich deine Aussage hier richtig verstehe, meinst du das gleiche wie ich.
Ich denke die meisten Referenzen kann der Compiler wegoptimieren um Speicher
zu sparen nur wenn es an das übergeben an Funktionen geht, dann benötigt man
die Adresse.Das meinst du doch auch oder?
-
Zeiger kann er auch wegoptimieren, das kanns also nicht sein.
-
Das meinst du doch auch oder?
Yup. Der Standard schreibt nicht vor, wieviel Speicher bzw. ob Referenzen Speicher belegen (es gibt in Standard-C++ auch keine Möglichkeit dies herauszubekommen oder Speicherbelegung zu erzwingen)
Wenn es also keine zusätzlichen Zwänge gibt (z.B. Referenz als Membervariable oder als Funktionsparameter) und der Compiler clever genug ist, dann kann eine Referenz durchaus auch ohne eigenen Speicherbereich (zur Laufzeit) implementiert werden.
Gerade für lokale Referenzen dürften die meisten Compiler das wohl machen.
-
Was ich jetzt genau nicht verstehe ist:Was die genau machen!
Auf auf die Gefahr hin dass mein Fachwissen noch sehr bescheiden ist, aber da ich mich auch grad mit Refernzen beschäftigt hab find ich CarstenJ's Beispiel ganz verständlich
#include <iostream> using namespace std; void funk(int &j) // Die Referenz j ist ein anderer Name für i... { j++; // Erhöhe j um eins... } int main() { int i=6; funk(i); // rufe die Funktion funkt mit i auf cout << i; // Gib i aus: i wurde in der Funktion verändert, hieß dort aber j }
In der Main-Funktion hast du eine Variable i mit derm Wert 6. Die Funtion funk übernimmt jetzt i als Argument (funk(i)) und wird ausgeführt, jedoch heißt der Parameter der Funktion nicht j sondern &j, was die Referenz kennzeichnet.
Wäre j keine Referenz, so würde i in der Main-Funktion nicht verändert werden und wäre also immer noch 6. Da j aber eine Referenz ist, wird i verändert und ist jetzt 7.Ich hoffe, das ist soweit richtig, wenn nicht korrigiert mic bitte, will ja nichts Falsches hier verbreiten...
-
Bashar schrieb:
Zeiger kann er auch wegoptimieren, das kanns also nicht sein.
Den Punkt verstehe ich ehrlich gesagt nicht. Ein Zeiger ist ein eigenes Objekt mit einer eigenen Identität. Diese kann ich direkt in Standard-C++ abfragen (ich kann z.B. die Adresse eines Zeigers bilden). Eine Referenz ist kein eigenes Objekt, besitzt keine eigene Identität. Ich kann weder erzwingen, dass eine Referenz eine Adresse (und damit Speicher) bekommt, noch selbiges abfragen.
Ein Compiler kann zwar sicher unter Berücksichtung der "as-if-Rule" bestimmte Zeiger wegoptimieren, aber dadurch werden Zeiger und Referenzen doch nicht gleich. Dadurch verlieren doch nicht die Aussagen bezüglich storage und storage-duration für Zeiger und Referenzen ihre Gültigkeit.Kannst du vielleicht noch mal genauer erklären, was du meinst? Oder wo ich falsch liege?
-
Das kommt drauf an, von welchem Standpunkt aus man das betrachtet. Vom Standard her ist alles klar: Zeiger sind Objekttypen, Referenzen nicht. Bums aus fertig.
Von der Implementation her gibt es aber IMHO keinen Unterschied zwischen einer Referenz und einem konstanten Zeiger, der nie als Lvalue benutzt wird. Und ich denke anschaulich passt das so auch sehr gut. Wenn ich keine Referenzen hätte, könnte ich das gleiche (modulo syntaktische Unbequemlichkeit) mit konstanten Zeigern erreichen, deren Adresse ich nicht abfrage.
-
Mir ist vollkommen klar, dass z.B. in meinem Beispiel, die Referenz wahrscheinlich wegoptimiert wird und direkt mit der Variablen gearbeitet wird.
Es geht um die Fälle, wo Referenzen "Sinn machen", zum Beispiel bei der Parameterübergabe, oder um array[][][][].bla schneller/einfacher zu referenzieren.
Von daher ist deine Kritik IMO nicht gerechtfertigt, weil wir darüber diskutiert haben, was bei Referenzen anders ist (und ob überhaupt etwas anders ist) wie bei Zeigern.
Und Zeiger können genauso wegoptimiert werden. Du kannst nicht einfach sagen, was ich sage stimmt nicht, weil sie wegoptimiert werden können.Das du die Adresse, auf die eine Referenz zeigt nicht abfragen/ändern kannst, dient nur deinem Schutz. Das ist ja einer der Vorteile von Referenzen.
-
Die Adresse, auf die eine Referenz zeigt, kann man über &ref doch prima abfragen - nur die Adresse der Referenz nicht
-
Von daher ist deine Kritik IMO nicht gerechtfertigt
Wo bitte habe ich kritisiert? Ich habe um eine Belegung deiner Aussage gebeten. Nicht mehr nicht weniger.
Du kannst nicht einfach sagen, was ich sage stimmt nicht, weil sie wegoptimiert werden können.
Habe ich auch nicht. Aber lass mal.
Desweiteren habe ich Bashar um Erklärung gebeten, da mein Bohnenhirn einfach zu klein zu sein scheint, als das ich diesen hingeworfenen Einzeilern folgen könnte.
Hier stand mehr oder weniger "Referenzen sind Zeiger". Und das habe ich bezweifelt.
Von der Implementation her gibt es aber IMHO keinen Unterschied zwischen einer Referenz und einem konstanten Zeiger, der nie als Lvalue benutzt wird.
Oh. Toll. Diese fundamentalen Einschränkungen konnte ich für meinen Teil bisher nicht aus dem Thread rauslesen. Vielleicht habe ich ja genau nach sowas gefragt? Denn interessanterweise bin ich da nicht mal anderer Meinung.
Aber naja, wie auch immer. Ihr habt recht und ich nicht. Ende.
-
HumeSikkins schrieb:
Hier stand mehr oder weniger "Referenzen sind Zeiger". Und das habe ich bezweifelt.
Das ist so natürlich falsch. Ich weiß nicht, ob Optimizer das wörtlich so meinte, oder doch eher "Referenzen sind Zeiger mit Einschränkungen x, y, z...".
Von der Implementation her gibt es aber IMHO keinen Unterschied zwischen einer Referenz und einem konstanten Zeiger, der nie als Lvalue benutzt wird.
Oh. Toll. Diese fundamentalen Einschränkungen konnte ich für meinen Teil bisher nicht aus dem Thread rauslesen.
Wenn wir uns einig darüber sind, dass Referenzen nicht verändert werden können und man ihre Adresse nicht bestimmen kann, aber trotzdem noch die Frage im Raum steht, ob Referenzen Zeiger mit Einschränkungen sind oder was völlig anderes, dann müssen wir beim Vergleich die verbleibenden Gemeinsamkeiten und Unterschiede beleuchten. Dass sie nicht exakt das gleiche sind liegt doch auf der Hand, darüber brauchen wir nicht zu diskutieren, das hat auch niemand behauptet.
-
mich hat diese Rechnerrei, ob Referenzen nun Speicher benötigen oder anlegen oder wegoptimiert werden ein wenig nachdenklich gemacht.
Um noch etwas Verwirrung zu schaffen. Kann mir das einer vorrechnen.
1+1=4? wieso 4
Benutze (VC6).
Außerdem sagt mir mein Überwachungfenster des Debuggers sizeof(sRef.r)=4!?struct sRef { char i; char &r; sRef():r(i){} }; struct sPure { char i; char r; sPure():r(i){} }; void foo() { sPure pure; sRef ref; std::cout<<sizeof(sRef)<<","<<sizeof(sPure)<<std::endl; std::cout<<sizeof(ref.i)<<","<<sizeof(ref.r)<<std::endl; std::cout<<sizeof(pure.i)<<","<<sizeof(pure.r)<<std::endl; } //2,4 //1,1 //1,1
-
1+1=4? wieso 4
Wegen des Alignments.
Und das hier ist ein Fall, bei dem Referenzen wohl kaum wegoptimiert werden können.
-
Helium schrieb:
1+1=4? wieso 4
Wegen des Alignments.
Und das hier ist ein Fall, bei dem Referenzen wohl kaum wegoptimiert werden können.
Also das versteh ich auch nicht!