Erläuterung Referenzen
-
ja sozusagen
stell dir vor der wert würde verändert... wo sollte er die veränderte variable denn ablegen?
-
Das Problem is hier nicht const oder Nicht-const sondern, dass du einer Referenz ein Literal zuweisen willst. Das geht nicht.
-
damals, als ich noch denken durfte, daß referenzen nur verkappte zeiger sind (hab noch nicht kapiert, warm ich es ncht darf, aber hume hat bestimmt recht), wäre mir klar gewesen, daß das nicht geht, weil man von 1 keine adresse ziehen kann.
bei "echten" referenzen gibt's eigentlich keinen grund. wenn sie bloß namen für andere sachen sind, warum sllten literale keine anderen namen kriegen dürfen?
-
volkard schrieb:
hab noch nicht kapiert, warm ich es ncht darf, aber hume hat bestimmt recht
-
interpreter schrieb:
Das Problem is hier nicht const oder Nicht-const sondern, dass du einer Referenz ein Literal zuweisen willst. Das geht nicht.
Die Referenz würde dann natürlich nicht an das Literal gebunden, sondern an eine temporäre Kopie. Das wiederum ist nur mit const-Referenzen erlaubt.
-
volkard schrieb:
damals, als ich noch denken durfte, daß referenzen nur verkappte zeiger sind
Den Ball muss ich aufnehmen:
Du bist ein erfahrener C++ Programmierer und darfst selbstvertändlich denken, was du willst und was dir am meisten weiterhilft. Ich glaube ich habe nur mal gesagt, dass ich es für keine gute Idee halte, einem Anfänger Referenzen nach dem Motto "Referenzen sind verkappte Zeiger..." zu erklären bzw. näherzubringen. Man kann mit Referenzen und Zeigern zwar das selbe erreichen und Referenzen werden häufig auch über Zeiger implementiert, wenn man diese Punkte in den Vordergrund stellt, konzentriert man sich imo aber auf die falschen (low-level) Details. Pointer sind z.B. Objekte und es gibt eine (wenn auch kleine) Menge von gültigen Operationen, Referenzen hingen sind keine Objekte und es gibt auch keine Operationen auf Referenzen. Eine Referenz ist ein Alias für ein vorhandenes Objekt, deshalb *kann* es auch keine Nullreferenz geben (und zwar schon aus logischer- und nicht nur aus Standard-C++-Sicht). Das ist für jemanden, der sich mehr auf die Unterschiede zwischen Pointern und Referenzen interessiert völlig einleuchtend. Konzentriert man sich hingegen auf die "low-level" Details, wird die Nullreferenz auf einmal wieder möglich -> Eine Nullreferenz ist ein "verkappter Pointer" auf den Nullpointer.Letztlich ist das für mich ein wenig so wie wenn man Methoden mit "Methoden sind nichts weiters als verkappte C-Funktionen die ein implizites Argument, nämlich einen Zeiger auf das aufrufende Objekt, erhalten" erklären würde. Es ist nicht verkehrt, wenn man dieses Detail bzw. diesen Zusammenhang kennt und versteht, es erklärt einem aber nicht, wann ich eine Funktion und wann eine Methode verwenden sollte, es macht letztlich nicht das Wesen einer Methode aus (zumindest wenn man nicht gerade im Kurs "Compilerbau für Einsteiger" sitzt). Genausowenig wie das Wesen einer Referenz durch den C/C++ Zeiger bestimmt ist.
Eher haben beide die Indirektions-Eigenschaft gemein. Vererbungstechnisch gesehen erbt Referenz nicht von Zeiger oder Zeiger von Referenz sondern beide von einer gemeinsamen Basisklasse.
(hab noch nicht kapiert, warm ich es ncht darf, aber hume hat bestimmt recht)
Es gibt neben mir meines Wissens nach keinen einzigen Menschen in diesem Forum der meiner Meinung einen besonderen Wert beimisst, also solltest du jetzt nicht damit anfangen.
*Mich* haben einfach die C++ Experten (z.B. Stephen Dewhurst, Marshall Cline, ...) die mehr auf die Unterschiede denn auf die Ähnlichkeit zwischen Referenzen und Pointern hinweisen mehr überzeugt.
Du hast halt andere Erfahrungen gemacht.wäre mir klar gewesen, daß das nicht geht, weil man von 1 keine adresse ziehen kann. bei "echten" referenzen gibt's eigentlich keinen grund. wenn sie bloß namen für andere sachen sind, warum sllten literale keine anderen namen kriegen dürfen?
Nullargument. Genausogut kann ich fragen: "Warum kann ich von 1 keine Adresse ziehn"? (Mir ist die Antwort aus Sicht der technischen Informatik klar, nicht aber aus rein logischer Sicht. Theoretisch könnten alle Elemente der natürlichen Zahlen eigenständige Objekte mit Identität sein von denen ich dann selbstverständlich dann auch die Adresse bilden könnte).
Das lustige ist doch, dass die Antwort auf beide Fragen letztlich die Selbe ist. Du kannst Literalen keinen *anderen* Namen geben, da Literale an sich keinen Namen haben. Sie sind keine (benannten) Objekte (im Sinne von lvalues). Und genau aus diesem Grund kannst du auch nicht die Adresse bilden. Könntest du die Adresse bilden, hättest du ein (benanntes) Objekt und hättest du ein solches Objekt, dann könntest du diesem auch einen anderen Namen geben.
-
Eine kleine technische Zwischenfrage: Der Standard macht ja keine Aussage darüber, WIE Compiler Referenzen umsetzen müssen und es leuchtet auch ein, dass es am geschicktesten per Pointer ginge. Aber welche Möglichkeit gäbe es denn überhaupt noch, Referenzen effizient OHNE Pointer umzusetzen?
-
Ich glaube ich habe nur mal gesagt, dass ich es für keine gute Idee halte, einem Anfänger Referenzen nach dem Motto "Referenzen sind verkappte Zeiger..." zu erklären bzw. näherzubringen.
konkret erinnere ich mich an einen link, wo einer ganz eindringlich erzählt hatte, daß referenzen keine zeiger seien.
Man kann mit Referenzen und Zeigern zwar das selbe erreichen und Referenzen werden häufig auch über Zeiger implementiert, wenn man diese Punkte in den Vordergrund stellt, konzentriert man sich imo aber auf die falschen (low-level) Details.
hm. also falsch, daß ich manches argument aus der tiefen schublade hole.
Pointer sind z.B. Objekte und es gibt eine (wenn auch kleine) Menge von gültigen Operationen, Referenzen hingen sind keine Objekte und es gibt auch keine Operationen auf Referenzen.
nullargument, da die sichtweise "referenzen malen bei verwendung *immer* das sternchen vor den namen, machen auch alle operationen kaputt. sie erklärt fein, daß referenzen initialisiert werden müssen (nachher kann man ja keinen wert mehr zuweisen).
außerdem erklärt die tiefe sichweise fein die ausgabe vonstruct Foo{ double &m_rdblData; Foo(): m_rdblData(gdblData){ } void test(){ cout<<sizeof(m_rdblData)<<' '<<sizeof(*this); } };
Eine Referenz ist ein Alias für ein vorhandenes Objekt, deshalb *kann* es auch keine Nullreferenz geben (und zwar schon aus logischer- und nicht nur aus Standard-C++-Sicht). Das ist für jemanden, der sich mehr auf die Unterschiede zwischen Pointern und Referenzen interessiert völlig einleuchtend. Konzentriert man sich hingegen auf die "low-level" Details, wird die Nullreferenz auf einmal wieder möglich -> Eine Nullreferenz ist ein "verkappter Pointer" auf den Nullpointer.
stimmt.
aber "Eine Referenz ist ein Alias für ein Objekt" ohne "vorhandenes" würde wieder nullreferenzen zulassen. warum steht "vorhandenes" da? warum müssen refs aus logischer sicht immer auf was vorhandenes zeigen? müssen sie as logischer sicht gar nicht, es wurde schlicht im standard so definiert. man hätte die definiton im standard leicht auch anders fassen können. will man sich nun behalten, warum der standard hier willkürlich nullreferenzen nicht zugelassen hat, hilft vielleicht ein blick in die geschichte. es gab mal eine zeit, da wurde die wegoptimierung von ri inint i=...; int &ri=i; int *pi=&i; ++ri; ++*pi;
offensichtlich implementiert, indem die beiden symboltabelleneinträge von i und ri auf die selben daten zeigten. das war eine art der optimierung, die so ganz anders als normale optimierungen sind. vorsichtiges standardisierungskommitee sagt sich sofort: wir lassen mal den compilerbauern möglichst viel luft, noch viel coolere optimierungen zu erfinden. man konnte so viel luft lassen, weil die verwendungen, wo referenzen echt notwendig sind, also copy-ctor und operatoren, nicht von alleine nullreferenzen anlegen.
heute können compiler aber sogar pi wegoptimieren.Letztlich ist das für mich ein wenig so wie wenn man Methoden mit "Methoden sind nichts weiters als verkappte C-Funktionen die ein implizites Argument, nämlich einen Zeiger auf das aufrufende Objekt, erhalten" erklären würde. Es ist nicht verkehrt, wenn man dieses Detail bzw. diesen Zusammenhang kennt und versteht, es erklärt einem aber nicht, wann ich eine Funktion und wann eine Methode verwenden sollte, es macht letztlich nicht das Wesen einer Methode aus (zumindest wenn man nicht gerade im Kurs "Compilerbau für Einsteiger" sitzt). Genausowenig wie das Wesen einer Referenz durch den C/C++ Zeiger bestimmt ist.
hmm. langsam kommt licht in die sache. das wesen einer methode also.
ein kieselstein ist ein kieselstein. ist es das wesen eines kieselsteins, eine mordwaffe zu sein? in meiner low-level-sichtweise eher nicht. da ist er ein stein. aus logischer sicht ist er was hübsches, was gefährtliches und was hartes. aber überanstrenge ich damit die arme logik nicht? diese "logik" ist nicht mehr, als eine empfehlung
suchst du was hübsches (zum anmalen und verschenken), ziehe kieselsteine in erwägung. suchst du was gefährliches (zum kaputtmachen von gegnern), ziehe kieselsteine in erwägung. suchst du was hartes (als stößel für deinen wildkräutermörser), ziehe kieselsteine in erwägung.
diese empfehlungen möchte ich eigentlich weit vom wesen getrennt halten. bin eh nicht sicher, daß tote dinge en wesen haben können. autos haben schonmal keines, die fahrer sind die bösen. auch pistolen sind nicht böse. und medicin wie heroin ist nicht von natur aus gut.
das wesen von dingen könnte ein minimaler satz von eigenschaften sein, der das ding (irgendwe ausreichend) beschreibt. ausreichend ist auf jeden fall, wenn das ding identifiziert werden kann. warum wünsche ich minimalität? ka, weil ich minimalist bin? ja, das könnte sein, daß hier der wurm begraben liegt.die beschreibenden eigenschaftenmengen werden kleiner, wenn man auf eher technischer seite operiert. (unbewiesen, oder?)
unabhängig von der technischen seite existiert natürlich noch eine ganze welt der meinungen, erfahrungen, empfehlungen. neben der sprache c++ existier noch der stil c++.
für mich ist der c++-compiler nicht mehr als ein recht brauchbarer makroassembler. auf den makroassembler für c wurden nur kleinigkeiten aufgesetzt, nämlich überladung durch name mangleing, methoden durch den geheimen this-zeiger, virtuelle methoden durch die vtbl, referenzen durch zeiger, und templates.
für mich hat es (die sprache technisch zu definieren) den unschätzbaren vorteil, daß mich keiner so leicht beschummeln kann. die technische seite kann ich nachvollziehen. da hab ich sowas wie axiome, auf die ich mich stützen kann.
ich würde weniger glücklich sein, wenn ich mch auf unzählige expertenmeinungen stützen müßte.Es gibt neben mir meines Wissens nach keinen einzigen Menschen in diesem Forum der meiner Meinung einen besonderen Wert beimisst, also solltest du jetzt nicht damit anfangen.
zu spät. vermutlich hätten tausende in diesem forum "du guckst zu low-level" sagen können und ich hätte mir nichts dabei gedacht. du aber hast so oft in eher undurschaubaren lagen recht (oder bringst (zitierst) gute argumente), daß ich mal über "du guckst zu low-level" nachgedacht habe. und wie ich finde, ist es beobachtenswert. wie schlägt sich denn der level auf die gefundenen meinugen zurück?
in desem zusammenhang würde mich interessieren, ob für Jester (den ich für einen mathematiker halte, der vermutlich viele axiome auf tiefstem level gewohnt ist) referenzen als verkappte zeiger empfindet oder als eigenständige dinge.
ich versuche mal bei mir unverständlichen meinungen (java ist toll) davon aszugehen, daß der meinungsvertreter ein ganz hohes level seiner definitionen hat. interessant wäre es, festzustellen, ob das denn einigermaßen widerspruchsarm überhaupt geht, oder ob das innendrin kunterbunt werden muß. und ich werde mal überdenken, ob ein c++-kurs mit konsequent hoch aufgehängten definitionen funktionieren kann.
ot: beachtet das falsche komme in "zeiger, und templates." oh, welch ein verbrechen würde man in der dummen schule sagen. aber ohne komma ist der satz nicht lesbar und ich muss entweder was ganz anderes schreiben, als ich sprechen würde, oder ein solch schweres kommaverbrechen begehen. mit komma ist er aber klar zu lesen. der fehler im system ist, daß ein deutschlehrer diesen kommafehler anstreichen und als fehler bewerten *muss*. er darf nicht absichtlich fehler übersehen, die er als tolerierbar oder gar als empfehlenswert ansieht. daran krankt auch die rechtschreibreform. am zwang. und deutsch wird zur toten sprache erklärt.
-
*gelöscht*
-
volkard schrieb:
in desem zusammenhang würde mich interessieren, ob für Jester (den ich für einen mathematiker halte, der vermutlich viele axiome auf tiefstem level gewohnt ist) referenzen als verkappte zeiger empfindet oder als eigenständige dinge.
Ich hatte eigentlich immer gehofft doch noch ein Informatiker zu werden.
Ehrlich gesagt habe ich noch sie so genau über den Unterschied meditiert, aber vielleicht sollte ich genau das mal tun.Dennoch zumindest das Argument von Hume mit der Vererbung zieht nicht, denn Zeiger erbt nicht von Referenz und Referenz nicht von Zeiger... und dennoch ist ein Quadrat ein Rechteck.
Andererseit sieht man an dieser Stelle genau den Unterschied zwischen High-Level und Low-Level:
Auf Low-Level ist ein Quadrat ein Rechteck. Wenn ich aber das "Wesen" eines Quadrates dazunehme (sein Verhalten bei Operationen), dann verschwindet das "ist ein" plötzlich und wir landen bei dem bekannten Beispiel.
-
volkard schrieb:
Pointer sind z.B. Objekte und es gibt eine (wenn auch kleine) Menge von gültigen Operationen, Referenzen hingen sind keine Objekte und es gibt auch keine Operationen auf Referenzen.
nullargument, da die sichtweise "referenzen malen bei verwendung *immer* das sternchen vor den namen, machen auch alle operationen kaputt. sie erklärt fein, daß referenzen initialisiert werden müssen (nachher kann man ja keinen wert mehr zuweisen).
Verstehe ich nicht. Da fehlt ein abschließendes ". Bis wohin soll die Erklärung gehen?
außerdem erklärt die tiefe sichweise fein die ausgabe von
struct Foo{ double &m_rdblData; Foo(): m_rdblData(gdblData){ } void test(){ cout<<sizeof(m_rdblData)<<' '<<sizeof(*this); } };
Richtig. Aber das erklärt mir nicht *was* Referenzen sind (Semantik) sondern nur *wie* sie häufig implementiert sind.
warum müssen refs aus logischer sicht immer auf was vorhandenes zeigen?
Siehste du schreibst "zeigen". Ich denke bei Referenzen aber nicht an "zeigen" sondern an "binden". Ich kann zwar meinen Fuß irgendwo und nirgendwo hin zeigen lassen. Nicht aber ein Seil nehmen und mich an nichts binden.
[..]Geschreibe über Wesen[...]
Ich wollte mit dem Wesen nicht auf irgendwas esotherisches hinaus. Mir ging es mehr um das Thema Semantik. Eine Methode gehört imo für mich in die Ecke von "konkrete Implementation einer Nachricht". Wenn ich über Methoden rede, bin ich im Bereich der OOP. Dann muss ich über Objekte, Nachrichten usw. reden. Wenn ich dann noch virtuell hinzunehme, dann muss ich zusätzlich Item 44 aus "Effective C++" lesen. Das meine ich mit "Wesen". Erst wenn ich das Verstanden habe, gehe ich los und lese Lippmans "Inside the C++ Object Model" und lerne wie das ganze innen drin aussehen könnte. Die Kombination der beiden Sichtweisen ist sehr mächtig. Nur womit fängt man an?Ich für meinen Teil fange meist mit der high-level Sicht an (Ich bin erstmal ein Mensch und kein Compiler/Computer. Aus diesem Grund betrachte ich die Welt erstmal nicht wie ein Compiler/Computer. Ich suche mir erstmal Metaphern außerhalb des Computers). Wenn *ich* z.B. beim Design von Hierarchien in Begriffen wie vtable, vptr und Offsetberechnungen bei Objekten mit mehreren Adressen denken würde, dann würde das mein Denken in die falsche Richtung lenken. Wenn ich allerdings eine Hierarchie implementiere und aufeinmal sagt mir mein Compiler, dass Foo die Methode bar per "Dominanz" erbt, dann ist das Wissen über low-level Details zweifelsohne sehr wertvoll. Wie gesagt, die Kombination der Sichtweisen ist der wahre bringer.
Über Kieselsteine kann ich hingegen nicht reden, da mir dazu das "Domain-Wissen" fehlt
Für mich hört sich der letzte Teil deines Beitrags ein wenig so an, als würdest du low level eine höhere Qualität zusprechen als high level. Ich denke aber nicht, dass das eine besser ist als das andere. Beide Sichtweisen sind für das Verständnis wichtig. Abhängig vom Kontext die eine mehr die andere weniger. Die Kunst beim Lernen/Lehren scheint es zu sein, auf welche Sicht man sich wann konzentriert.
Und hier haben wir was das Thema Referenzen angeht wohl eine unterschiedliche Sichtweise
-
Also ich sehe die referenzen auch als "verkappte" aber konstante Zeiger an ....
Verkappt, weil ich sie nicht dereferenzieren brauch, und sie keinen explizieten ungueltigkeitswert haben (ich kann ned auf gueltigkeit testen, ich muss mich drauf verlassen)
konstannt, weil ich die "Addresse" auf die sich eine referenz bezieht (oder zeigt) nicht aendern kann.
Als eine bindung seh ich es nicht weil ..... Ich kann referenzen auf speicherbereiche anderer typen zeigen lassen (oder binden).
char test[32];
short & myref (reinterpret_cast<short &>(test[2]));An was hab ich die referenz jetzt gebunden ? an ein fragment von test ? Das laesst sich eben mit "zeigen" und "Adressen" einfach einfacher erklaeren ...
Sicher sollte man sich aber der drastischen Anederung der Philosophie sein, die die wenigen aber bedeutenden Unterschiede mit sich bringen.
Aber so kann man auch ueber andere dinge diskutieren .... ein klitzekleines Detail kann den kompletten Context umwerfen, komplette Philosophien umwerfen oder moeglich machen ....
Ich fuer mich denk, das zeiger und referenzen das wesentlichste gemeinsam haben, aber sich in einigen , trotzdem wichtigen details, unterscheiden ....
Ciao ...