Pointer vs. Referenz



  • c++fan 2009 schrieb:

    David_pb schrieb:

    Sowas macht man ja auch nicht! 🙂

    Ja, trotzdem kann eine Referenz überall hin zeigen wie ein Zeiger. Cast sei Dank.

    Auf fast alles! 😉



  • Belli schrieb:

    ...wenn ich Referenzen immer als const übergebe, und nur in Fällen, wo ich ändern können muß, Zeiger benutze (eventuell noch, wenn ich 0(NULL) übergeben können muß), erleichtert mir das die Lesbarkeit, weil ich mich dann auf bestimmte Dinge verlassen kann....

    Hmmm .... non-const-Referenzen und const-Zeiger verwendest Du nicht?

    Ich verlasse mich inzwischen lieber nur noch auf Dinge, die mir der Standard zusichert - alles Andere beißt Dir sowieso in den Hintern, weil es genau in dem einen von 100 Fällen nicht stimmt, auf den es ankommt.

    Ist das gleiche Argument wie bei Variablenbenamsung wie pZeiger , aucArray und m_Member ... es gibt nichts Schlimmeres als sich auf Unzuverlässiges zu verlassen ... dann ist man verlassen. 😉

    Belli schrieb:

    ...Wenn man nun den Code liest und verstehen will, ist das an der Stelle, wo der Aufruf erfolgt, dann nicht erkennbar, wenn man Referenzen benutzt, weil der Aufruf mit einer Referenz sich nicht von einem Aufruf mit einem Wert unterscheidet....

    Was ich für eine gute Idee halte, weil zum Thema "Änderbarkeit" das const-Konzept eingeführt wurde und "Zeiger/Referenzen" damit eigentlich nichts zu tun haben.

    Gruß,

    Simon2.



  • c++fan 2009 schrieb:

    David_pb schrieb:

    Sowas macht man ja auch nicht! 🙂

    Ja, trotzdem kann eine Referenz überall hin zeigen wie ein Zeiger. Cast sei Dank.

    Nen Cast braucht man ja nicht unbedingt, man dereferenziert einfach den Zeiger.

    int* foo();
    void safe( int& i );
    
    safe( *foo() );
    


  • c++fan 2009 schrieb:

    Chris++ schrieb:

    Also Referenzen sind ja im Pinzip Pointer die nicht NULL sein dürfen.

    Aber können!
    ...

    Aber da "ist" doch die Referenz nicht 0, sondern du de-referenzierst halt einen ungültigen Zeiger:

    c++fan 2009 schrieb:

    f ((int&)     
       *        // hier dereferenzierst Du einfach 0
    (int*)0);
    

    Dass das zu einem undefinierten Verhalten führt, ist weder überraschend noch hat es was mit Referenzen zu tun.

    ich weiß, dass Referenzen auch auf ungültige Objekte zeigen können, aber allein die Tatsache, dass man das bei Referenzen gar nicht überprüfen KANN, erledigt die ursprüngliche Diskussion darüber, ob man es bei Zeigern soll/muss oder nicht.
    Ich darf mich bei der Verwendung von Referenzen darauf verlassen, dass mir der Aufrufer ein gültiges Objekt übergibt, weil ich gar keine Alternative habe....

    c++fan 2009 schrieb:

    David_pb schrieb:

    Sowas macht man ja auch nicht! 🙂

    Ja, trotzdem kann eine Referenz überall hin zeigen wie ein Zeiger. Cast sei Dank.

    Dem würde ich auch widersprechen und sagen: Man darf in C halt rumcasten und dereferenzieren wie man will ... aber das hat nichts mit Referenzen zu tun.
    Genauso könnte ich sagen: "Ein int kann auch ein string sein" ... bloß weil ich das irgendwie miteinander "vercasten" kann.

    Gruß,

    Simon2.



  • Belli schrieb:

    Ich bleibe dabei, wenn ich Referenzen immer als const übergebe, und nur in Fällen, wo ich ändern können muß, Zeiger benutze (eventuell noch, wenn ich 0(NULL) übergeben können muß), erleichtert mir das die Lesbarkeit, weil ich mich dann auf bestimmte Dinge verlassen kann.

    sehr schön. 🙂
    so halte ich das auch.
    aber swap wird mit referenzen gebaut, weil das schon immer so war.



  • volkard schrieb:

    Belli schrieb:

    Ich bleibe dabei, wenn ich Referenzen immer als const übergebe, und nur in Fällen, wo ich ändern können muß, Zeiger benutze (eventuell noch, wenn ich 0(NULL) übergeben können muß), erleichtert mir das die Lesbarkeit, weil ich mich dann auf bestimmte Dinge verlassen kann.

    sehr schön. 🙂
    so halte ich das auch.
    aber swap wird mit referenzen gebaut, weil das schon immer so war.

    Schonmal meinen Code gelesen? ... oder den von Anderen, die diese Regel nicht beherzigen? :p 😉

    Gruß,

    Simon2.

    P.S.: Mir ist nicht nur kein Code untergekommen, der diese Regel umgesetzt hätte ... auch noch keiner, bei dem drüber steht "ACHTUNG! Dieser Code hält sich nicht konsequent an die volkhardsche Parameter-Zeigersemantik!"



  • bei fremden Code kannst du dich nicht drauf verlassen und bei eigenem Code kannst du auch folgendes schreiben:

    #define OUT
    
    void foo(int& i)
    	{
    	i = 3;
    	}
    
    int main()
    	{
    	int a;
    	foo(OUT a);
    	}
    

    Is zwar ungewohnt, aber man sollte wissen was gemeint ist! Dass das nicht üblich ist, ist klar, aber es ist nicht weniger sicher als davon auszugehen, dass Pointer automatisch outputparameter sind?

    (Zur Anmerkung: natürlich denke ich nicht, dass man das machen sollte, aber es ist genau das selbe o.O OUT kann alles sein, ist im Prinzip aber nur zu lesbarkeit, genau so verhält es sich mit Pointern an dieser Stelle. Im Prinzip ist OUT sogar besser, weil man dann intern Referenzen verwenden kann und nicht auf die Gefahr läuft 0 übergeben zu bekommen.)



  • *hust* OUT *hust*



  • verdammt, mein ich ja..

    edit: sagt mal... ist euch der Name des Threaderstellers aufgefallen? 🤡



  • JustAnotherNoob schrieb:

    bei fremden Code kannst du dich nicht drauf verlassen...

    Eben.
    Und was hilft mir eine Regel, auf die ich mich weder verlassen noch deren Verlässlichkeit ich überprüfen kann?
    ... und das alles für eine Information, für die es bereits ein standardisiertes, zuverlässiges und automatisiertes Verfahren gibt ("const") ?
    Dann besser keine Regel...

    Gruß,

    Simon2.



  • JustAnotherNoob schrieb:

    edit: sagt mal... ist euch der Name des Threaderstellers aufgefallen? 🤡

    Hehe. Ich denke, der Krieg im anderen Thread reicht, zumal sich die Argumente stark überschneiden. Trotzdem interessant, wie viele hier noch einmal ihre Position vertreten wollen... 😉



  • Simon2 schrieb:

    Und was hilft mir eine Regel, auf die ich mich weder verlassen noch deren Verlässlichkeit ich überprüfen kann?

    Das ist überall so.
    getFoo() ist für mich ein getter, aber für andere vielleicht die funktion zum initialisieren von Bar().

    Idiome verwendet man, weil es sinn macht sie zu verwenden - denn auf irgendwas müssen wir uns verlassen, wir müssen den anderen programmierern trauen. Sonst können wir ihren code nicht verwenden.

    ... und das alles für eine Information, für die es bereits ein standardisiertes, zuverlässiges und automatisiertes Verfahren gibt ("const") ?
    Dann besser keine Regel...

    Äh, der Punkt ist dass const zwar nett ist und const nimmt dir auch keiner weg - der Punkt ist, dass const nur im callee aufscheint aber nicht im caller.

    Und es geht um die kennzeichnung beim call... Und da hilft dir const garnichts.



  • Shade Of Mine schrieb:

    ...
    Und es geht um die kennzeichnung beim call... Und da hilft dir const garnichts.

    Ich weiß ... aber da hilft mir ja ein "&" anscheinend auch nicht unbedingt etwas...

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Shade Of Mine schrieb:

    ...
    Und es geht um die kennzeichnung beim call... Und da hilft dir const garnichts.

    Ich weiß ... aber da hilft mir ja ein "&" anscheinend auch nicht unbedingt etwas...

    Gruß,

    Simon2.

    Es ist aber zumindest ein Indiz, das auf die Möglichkeit hinweist. Nach dem Motto "besser als gar nix"! Und in Verbindung mit eigenem Code vermischt sich dieses Indiz mit der eigenen Erinnerung oft zur Gewissheit.



  • _matze schrieb:

    ...Es ist aber zumindest ein Indiz, das auf die Möglichkeit hinweist. Nach dem Motto "besser als gar nix"! Und in Verbindung mit eigenem Code vermischt sich dieses Indiz mit der eigenen Erinnerung oft zur Gewissheit.

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?
    - 0 erläubt?
    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)
    - irgendwelche "Speicherschweinereien" geplant?
    - auto-Objekt ("Stack") erlaubt?
    - ...

    Aber ich muss auch sagen: Die Qualität von Code hängt IMHO auch nicht zentral der Nicht-/Verwendung dieser Regel ab ... 😉

    Gruß,

    Simon2.



  • [quote="Simon2"]

    _matze schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?
    - 0 erläubt?
    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)
    - irgendwelche "Speicherschweinereien" geplant?
    - auto-Objekt ("Stack") erlaubt?
    - ...

    Für mich geht es einfach und allein darum, daß ich bei Wartung, Pflege, Analyse von selbst geschriebenem Code beim Aufruf einer Funktion ohne Zeiger weiß, daß mein Parameter nach Rückkehr unverändert ist, OHNE daß ich mir die Funktionsdeklaration ansehen muß.
    Bei Übergabe eines Zeigers weiß ich, daß der Parameter nach Rückkehr verändert sein KANN.
    MIR erleichtert das Analyse und Fehlerrecherche.

    Wenn man Software im Team entwickelt und Teamintern eine solche Verfahrensweise einhält, ist das auch sehr hilfreich.

    Daß die Qualität von Code von dieser Verfahrensweise nicht zentral abhängt, denke ich auch.

    Ich würde das Ganze auch nicht als Regel bezeichnen, es ist halt eine Verfahrensweise, die manchen möglicherweise das Leben an der ein oder anderen Stelle etwas erleichtern kann - nur meine Meinung.



  • [quote="Belli"]

    Simon2 schrieb:

    _matze schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?
    - 0 erläubt?
    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)
    - irgendwelche "Speicherschweinereien" geplant?
    - auto-Objekt ("Stack") erlaubt?
    - ...

    Für mich geht es einfach und allein darum, daß ich bei Wartung, Pflege, Analyse von selbst geschriebenem Code beim Aufruf einer Funktion ohne Zeiger weiß, daß mein Parameter nach Rückkehr unverändert ist, OHNE daß ich mir die Funktionsdeklaration ansehen muß.
    Bei Übergabe eines Zeigers weiß ich, daß der Parameter nach Rückkehr verändert sein KANN.
    MIR erleichtert das Analyse und Fehlerrecherche.

    Wenn man Software im Team entwickelt und Teamintern eine solche Verfahrensweise einhält, ist das auch sehr hilfreich.

    Selbst wenn du es in deinem Team einhältst bringt es noch nicht wirklich viel, weil externe Libs es nicht so machen müssen außerdem bedeutet Pointer ja nicht zwangsläufig, dass das Object verändert wird und dann musst du doch wieder nachschauen.

    Und wirklich interessant ist das ganze auch nicht. Ich hab schon mit ner Menge fremden Code gearbeitet und debuggt, aber ob ein Objekt in einer Funktion verändert wird oder nicht, war eigentlich nie ein Problem.



  • Belli schrieb:

    ...Für mich geht es einfach und allein darum, daß ich bei Wartung, Pflege, Analyse von selbst geschriebenem Code beim Aufruf einer Funktion ohne Zeiger weiß, daß mein Parameter nach Rückkehr unverändert ist, OHNE daß ich mir die Funktionsdeklaration ansehen muß....

    "Es geht sich um Folgendes ...." 😉
    Ich möchte hier diskussionstechnisch mal unterscheiden zwischen 2 Situationen:
    A) Ich stolpere beim Maintance-Aufgabe über ein Stück Source der Form f(&x) . Da kommt mir die Idee "Aha! Diese Funktion könnte den Zustand von x verändern.
    Oder über ein Stück Code der Form std::string const s="Simon2"; f(s); . Da kommt mir die Idee "Aha! Diese Funktion wird diesen String wahrscheinlich nicht verändern."[/c].
    Diesen Gedankengang finde ich naheliegend und teile ihn auch.

    😎 Ich überlege mir eine neue Schnittstelle für meine Bibliothek und stehe vor der Frage "Wie soll die Parameterübergabe entworfen werden?".
    Dann kommt mir der Gedanke: "Da das ein update-Parameter werden soll, nehme ich einen Zeiger oder eine Refernzen. Damit der Benutzer (bzw. ein späterer 'Maintainer') direkt erkennen kann, dass es sich um einen update-Parameter handelt, entscheide ich mich für einen Zeiger."
    Diesen (kursiv hervorgehobenen) Gedankengang würde ich nicht teilen - aus den o.g. Gründen.

    Die Ausgangsfrage dieses Threads schien mir in Richtung 😎 zu gehen ... aber vielleicht ist das Alles auch nur ein schrecklicher Irrtum. 😉

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?

    Das kommt daher dass man immer sagt: Zeiger sind böse. Aber das sind sie nicht. Zeiger sind deine Freunde.

    - 0 erläubt?

    uninteressant beim code lesen. ist aber ein standard precondition fall. hat man bei referenzen und auch bei by value übergaben ebenfalls (in welchem zustand muss das objekt sein)

    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)

    Hat rein garnichts mit Zeigern zu tun

    - irgendwelche "Speicherschweinereien" geplant?

    Nein.
    Du musst dem Code vertrauen - wenn du ihm nicht vertraust, dann warte ihn nicht.
    Speicherschweinereien kann ich mit Referenzen genauso machen.

    - auto-Objekt ("Stack") erlaubt?

    ja, immer.

    😎 Ich überlege mir eine neue Schnittstelle für meine Bibliothek und stehe vor der Frage "Wie soll die Parameterübergabe entworfen werden?".
    Dann kommt mir der Gedanke: "Da das ein update-Parameter werden soll, nehme ich einen Zeiger oder eine Refernzen. Damit der Benutzer (bzw. ein späterer 'Maintainer') direkt erkennen kann, dass es sich um einen update-Parameter handelt, entscheide ich mich für einen Zeiger."
    Diesen (kursiv hervorgehobenen) Gedankengang würde ich nicht teilen - aus den o.g. Gründen.

    Der Punkt ist nicht ob du es auch so machst sondern ob du verstehst warum es Sinn machen kann es so zu machen.
    Ich persönlich verwende nicht für OUT parameter Zeiger - aber ich verstehe den Gedankengang und sehe die Probleme die man damit löst.



  • Shade Of Mine schrieb:

    Simon2 schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?

    Das kommt daher dass man immer sagt: Zeiger sind böse. ...

    Nicht ganz.
    Sondern weil man
    a) 99% der Dinge ohne Zeiger machen kann und das
    b) in den allermeisten Fällen einfacher (nix mit -> oder 0-Prüfungen oder ...)

    Dafür haben Zeiger bestimmte Möglichkeiten, die sie für bestimmte Situationen ideal machen (deswegen sind sie auch meine Freunde).

    Shade Of Mine schrieb:

    ...
    Der Punkt ist nicht ob du es auch so machst sondern ob du verstehst warum es Sinn machen kann es so zu machen.
    Ich persönlich verwende nicht für OUT parameter Zeiger - aber ich verstehe den Gedankengang und sehe die Probleme die man damit löst.

    Moment: Nirgendwo habe ich gesagt, dass ich den Gedankengang nicht verstünde .... ich halte es nur nicht für die beste (und nicht einmal für eine erstrebenswerte) Herangehensweise an ein Problem ("Wie erkenne ich OUT-Parameter?").

    Gruß,

    Simon2.


Anmelden zum Antworten