Größe von Referenzen?
-
Hi, wie groß ist eigentlich eine Referenz bzw. ab wieviel bytes lohnt es sich Parameter per Referenz an eine Funktion zu übergeben?
Gruß
Referencer
-
Technisch gesehen ist das so etwas wie ein Pointer und es gelten daher die gleichen Größenangaben.
-
Für den Compiler ist es das gleiche wie ein Pointer. Für den Programmierer ist er sicherer, da eine Referenz nicht 0 sein kann.
-
PtrPtr schrieb:
Für den Programmierer ist er sicherer, da eine Referenz nicht 0 sein kann.
Das ist schwachsinn. In vielen Fällen kann es sinnvoll und erwünscht sein, einen 0-Wert zu haben. Und Dangling references verweisen nicht mehr auf Objekte.
-
Man kann eigentlich drüber diskutieren ob eine Referenz überhaupt ein eigenständiges Objekt ist. So ist es z.b. nicht möglich die Adresse einer Referenz zu bestimmen und es ist undefiniert ob eine Referenz überhaupt sowas wie eine Größe hat. Und damit fehlen einer Referenz eigentlich die wesentlichen Eigenschaften eines Objekts. Dazu kommt dass eine Referenz für immer an ein Objekt gebunden ist. Insgesamt gibts da imo also doch große semantische Unterschiede. Rein funktional betrachtet kannst du dir Referenzen als sowas Ähnliches wie Pointer vorstellen und der Compiler wird Referenzen intern wohl oft einfach über Pointer implementieren, aber wohl auch nicht immer (er wird z.B. in bestimmten Fällen evtl. Objekte direkt referenzieren, z.B. wenn er was inlined) und auf Sprachebene schreibt das auch niemand vor.
Ich würde sagen wann Übergabe als Referenz besser ist als Wertübergabe kann man nicht so einfach sagen. Die Faustregel wäre primitive Typen (int, double, ...) als Wert zu übergeben und komplexere Typen als Referenz. Allerdings würde ich sagen das hängt auch davon ab wie diese Objekte dann verwendet werden. Wenn du ein etwas komplexeres Objekt hast, das aber sehr sehr oft referenziert wird, könnte es vielleicht passieren, dass der Overhead durch die zusätzliche Indirektion größer wird als der Overhead durch einmaliges Kopieren. Absolute Gewissheit bekommt man nur indem man den konkreten Fall profiled.
Vielleicht ganz interessant: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
-
Ich sehe keinen Gewinn darin, zu leugnen, daß Referenzen verkappte Zeiger sind.
Viele Fragestellungen kann man mit dieser Sichtweise sinnvoll beantworten, wiestruct Foo { Bar& b; };wie groß ist sizeof(Foo)?
Und rund wird es, wenn man noch dazusagt, daß Referenzen durchaus anders implementiert sein könnten. Dann erwartet man zwar, daß ein Foo 4/8 Bytes groß ist, weiß aber auch, daß es dafür keine Zusage gibt.
-
Warum gibts eigentlich keine void&'s?
-
Weil es in C++ Mechanismen gibt, die das wofür void* gebraucht werden überflüssig machen (und void* gibt's ja trotzdem noch). Daher bleibt als Verwendungszweck einer void& nur der Zugriff auf ein void-Objekt. Hmm.

-
314159265358979 schrieb:
Warum gibts eigentlich keine void&'s?
Wie soll man diese initialisieren?
-
int answer_to_everything = 42; void& answer = answer_to_anything;
-
Und was willst du mit dieser Reference to void dann anstellen?
-
Das Konzept hinter Referenzen ist ja, dass sie nach der Initialisierung genau gleich wie das eigentlich Objekt zu benutzen sind, oder? Und wenn ich nun etwas mit
answermachen will, müsste ich es zuerst casten. Und das würde dieses Konzept ausser Kraft treten lassen.
-
dot schrieb:
Und was willst du mit dieser Reference to void dann anstellen?
Ganz normal wieder hochcasten.
Also verwenden wie einen void*, aber mit dem Unterschied, daß eine void& nicht *nullptr referenzieren darf. Zum Beispiel für Datenstrukturen, die nur sehr wenig über die verwalteten Daten wissen müsen, um template-Instanzen klein zu halten und gemeinsamen Code der allgemeinen Verwaltung zu benutzen.
template<typename T> class Datenstruktur { AllgDatenstruktur data; T& peek() { void& v=data.peek(); return static_cast<T&>(v); }Mit void* muß der Compiler davon ausgehen, daß data.peek() einen nullptr liefern könnte. Da könnte ihn je nach Maschine dazu zwingen, anzunehmen, eine NullPointerException könne fliegen oder ihn wenigstens von mancher Optimierung abhalten. Und der Programmierer weiß auch, daß peek() immer ein Objekt zurückliefert.
-
---
-
Referencer schrieb:
Hi, wie groß ist eigentlich eine Referenz
3.82m
-
volkard schrieb:
...
Aber dazu ist doch schon der Templateparameter da.
template<typename T> class Datenstruktur { AllgDatenstruktur data; T& peek() { T& v = static_cast<T&>(data.peek()); // Es ist ja schon vorausgesetzt, dass peek() in T& castbar ist. return v; // Oder v gleich weglassen. }
-
SeppJ schrieb:
volkard schrieb:
...
Aber dazu ist doch schon der Templateparameter da.
template<typename T> class Datenstruktur { AllgDatenstruktur data; T& peek() { T& v = static_cast<T&>(data.peek()); // Es ist ja schon vorausgesetzt, dass peek() in T& castbar ist. return v; // Oder v gleich weglassen. }Ja, aber data.peek() muß eine void& zurückgeben.
-
volkard schrieb:
Ich sehe keinen Gewinn darin, zu leugnen, daß Referenzen verkappte Zeiger sind.
Viele Fragestellungen kann man mit dieser Sichtweise sinnvoll beantwortenAber viele entstehen auch erst durch diese Sichtweise. Adressierbarkeit, Wertsemantik, Speicherung in Arrays, Grössenermittlung, Veränderbarkeit... Alles Themen, die aufkommen, weil man versucht, Referenzen wie Objekte anzusehen. Die Indirektion ist natürlich wie bei Zeigern vorhanden, aber grundsätzlich kommt die abstrakte Vorstellung eines Alias recht nahe hin.
Aber
void&fände ich schon etwas befremdlich. Schon mitvoid*kann man fast nichts anstellen, aber mitvoid&? Da ist sogar der ganz normale Zugriff ein Fehler.
-
314159265358979 schrieb:
PtrPtr schrieb:
Für den Programmierer ist er sicherer, da eine Referenz nicht 0 sein kann.
Das ist schwachsinn. In vielen Fällen kann es sinnvoll und erwünscht sein, einen 0-Wert zu haben. Und Dangling references verweisen nicht mehr auf Objekte.
Dann könnte man sich die Referenz auch sparen und nur mit Pointer arbeiten.
-
PtrPtr schrieb:
314159265358979 schrieb:
PtrPtr schrieb:
Für den Programmierer ist er sicherer, da eine Referenz nicht 0 sein kann.
Das ist schwachsinn. In vielen Fällen kann es sinnvoll und erwünscht sein, einen 0-Wert zu haben. Und Dangling references verweisen nicht mehr auf Objekte.
Dann könnte man sich die Referenz auch sparen und nur mit Pointer arbeiten.
Was meinst du, warum es immer noch Pointer in C++ gibt? Es gibt noch genug Situationen, in denen eine Referenz nicht ausreicht.