Wann Referenzen, wann Pointer?



  • Denk EOutOfResources hat es schon passend ausgedrueckt.

    Referenzen wo man kann,
    Pointer wo man "muss"

    Damit reduziert sich die anwendung von Zeigern an diesen Stellen auf ein paar wenige valide Gruende:

    - Ungueltige Objekte. Nicht jedes Object kann ich in der Programmlogik so bauen, das es quasi einen ungültigkeitswert bekommt. Da referenzen immer gueltig sein muessen, könnt ich mit denen nicht signalisieren "Hallo, lass mich in ruhe, ich bin eigentlich ungueltig". Dafür bieten sich dann pointer an !

    - Kompatiblitaet zu vorherigen Code. Wenn jemand vor mir (ne Bib oder Framework) schon pointer wegen dem ungeultigkeitszeug verwendet, wuerde es unnötig komplex werden, das auf referenzen runterzubrechen.

    - Ab und an braucht man eine variable, die zur Laufzeit auf unterschiedliche Objecte Zeigt, wo das Object quasi ausgetauscht wird ... versuch das mal mit referenzen und sauberen C++ Stil 🙂

    Ciao ...



  • RHBaum schrieb:

    versuch das mal mit referenzen und sauberen C++ Stil 🙂

    Der Stil wird durch Referenzen nicht sauberer.
    Ihr überstrapaziert die Referenzen. Das ist die selbe Schiene wie das Verwenden von std::string für *alle* Zeichenketten, weil es "mehr C++" ist. Nix gut.
    Die Referenzen mußten für die Operatorenüberladung erfunden werden. Ok, jetzt haben wir sie. Aber den Haupt-Code verschlimmern sie leider. Deswegen empfiehlt Onkel Volkard: Sparsam einsetzen.

    Meine Debugsession sieht so aus:

    c=siquo(b,c);
    bar.foo(a,&b);//patsch, NUR hier kann b kaputtgegangen sein
    print(b);
    

  • Administrator

    Meine Debugsession sieht so aus:
    Ich setze einen Watchpoint auf b und lasse den Debugger die Arbeit für mich erledigen 😉

    Im übrigen hast du den Satz von RHBaum völlig aus dem Kontext gerissen. Und wieso deine Debugsession nicht unbedingt funktionieren muss, wurde auch schon aufgezeigt. Zudem hat hier überhaupt niemand empfohlen, dass man ausschliesslich Referenzen einsetzen soll. Bei std::string gilt auch, dass man ihn meistens nur in Spezialfällen durch ein char const* oder ähnliches ersetzen kann.

    Grüssli



  • Dravere schrieb:

    Meine Debugsession sieht so aus:
    Ich setze einen Watchpoint auf b und lasse den Debugger die Arbeit für mich erledigen 😉

    Kopf ist schneller als Debugger.

    Dravere schrieb:

    Im übrigen hast du den Satz von RHBaum völlig aus dem Kontext gerissen.

    Nö. Sein Konstrukt zieht die Verwendung von Referenzen und den guten C++-Stil rhetorisch in eine Nähe, die ich so nicht stehen lassen wollte.

    Dravere schrieb:

    Und wieso deine Debugsession nicht unbedingt funktionieren muss, wurde auch schon aufgezeigt.

    Kein Mittel ist erschöpfend.

    Dravere schrieb:

    Zudem hat hier überhaupt niemand empfohlen, dass man ausschliesslich Referenzen einsetzen soll.

    Doch, RHBaum war das.

    Dravere schrieb:

    Bei std::string gilt auch, dass man ihn meistens nur in Spezialfällen durch ein char const* oder ähnliches ersetzen kann.

    Stringliterale (Spezialfälle) sind char-Arrays. Ich brauche einen Grund, sie zu string zu machen.


  • Administrator

    volkard schrieb:

    Kopf ist schneller als Debugger.

    Und macht mehr Fehler, siehe auch ->

    volkard schrieb:

    Kein Mittel ist erschöpfend.

    volkard schrieb:

    Nö. Sein Konstrukt zieht die Verwendung von Referenzen und den guten C++-Stil rhetorisch in eine Nähe, die ich so nicht stehen lassen wollte.

    ... sogar wenn du damit nur Spass machst, ist es einfach nur blöd.

    volkard schrieb:

    Doch, RHBaum war das.

    Kauf dir eine Brille ...

    volkard schrieb:

    Stringliterale (Spezialfälle) sind char-Arrays. Ich brauche einen Grund, sie zu string zu machen.

    Um damit zu arbeiten?

    Das ist mir zu blöd. Wenn man keine Argumente mehr hat ...

    Grüssli



  • volkard schrieb:

    RHBaum schrieb:

    versuch das mal mit referenzen und sauberen C++ Stil 🙂

    Der Stil wird durch Referenzen nicht sauberer. Ihr überstrapaziert die Referenzen.

    Sehe ich anders. Wenn ich Zeiger übergebe ist NULL zulässig, und das ist zumindest bei den überwiegenden Fall in den Programmen, eher die Ausnahme als die Regel. Einer Referenz sieht man an, das ein Wert erwartet wird, einem Zeiger nicht. Einen Zeiger muss man zudem eigentlich immer vor der Verwendung prüfen. Ich glaube daher schon, das Referenzen immer Zeigern vorzuziehen sind, wenn man letztere nicht benötigt.

    volkard schrieb:

    Das ist die selbe Schiene wie das Verwenden von std::string für *alle* Zeichenketten, weil es "mehr C++" ist. Nix gut.

    Ich sehe in der überwiegenden Mehrzahl keine Gründe die für char-Arrays gegenüber (einer wie auch immer gearteten) Stringklasse sprechen.



  • volkard schrieb:

    Aber den Haupt-Code verschlimmern sie leider.

    Warum? Nur weil du nicht von außen siehst wo eine Variable geändert wird?



  • IntelliSense zeigt das doch an.



  • EOutOfResources schrieb:

    IntelliSense zeigt das doch an.

    Nicht jeder hat IntelliSense 😉



  • wwwwwwwwwww schrieb:

    volkard schrieb:

    Aber den Haupt-Code verschlimmern sie leider.

    Warum? Nur weil du nicht von außen siehst wo eine Variable geändert wird?

    Das siehst du aber auch keinen Zeiger an.



  • asc schrieb:

    wwwwwwwwwww schrieb:

    volkard schrieb:

    Aber den Haupt-Code verschlimmern sie leider.

    Warum? Nur weil du nicht von außen siehst wo eine Variable geändert wird?

    Das siehst du aber auch keinen Zeiger an.

    Volkard benutzt bestimmt nur dort Zeiger, wo die Parameter auch geändert werden. Sehr diszipliniert. Respekt. :p



  • volkard schrieb:

    Der Stil wird durch Referenzen nicht sauberer.
    Ihr überstrapaziert die Referenzen. Das ist die selbe Schiene wie das Verwenden von std::string für *alle* Zeichenketten, weil es "mehr C++" ist. Nix gut.
    Die Referenzen mußten für die Operatorenüberladung erfunden werden. Ok, jetzt haben wir sie. Aber den Haupt-Code verschlimmern sie leider. Deswegen empfiehlt Onkel Volkard: Sparsam einsetzen.

    Wow! Ich hätte dir niemals derart liberales Gedankengut zugetraut... 😃
    Und insbesondere die indirekte Verherrlichung von char-Arrays... also pfui! Und sowas in einem C++-Forum, wo der STL-Monotheismus exzessiv praktiziert und propagiert wird! 😃

    Im Übrigen halte ich es so wie einige andere auch.

    Wann immer es geht übergebe ich per Referenz wenn möglich auch const. Wo es NULL sein darf, auch mal Pointer... Ich bin also flexibel in der Anwendung 🙂



  • asc schrieb:

    Das siehst du aber auch keinem Zeiger an.

    Aber manch einer erwartet es bei einem Pointer vielleicht eher.
    Du vielleicht nicht, ich auch nicht, aber andere schon.



  • Meiner Meinung nach ist der Punkt der:
    Wenn ich einen Pointer übergebe, dann weiß ich, daß das Objekt, auf das gezeigt wird, geändert werden kann, ohne dass ich mir die Deklaration/Definition der aufgerufenen Funktion ansehen muss.
    Wenn ich ein Objekt übergebe, dann sehe ich an der Aufrufstelle nicht, ob die aufgerufene Funktion das als Objekt oder als Referenz nimmt. Bei der Entwicklung ist mir das noch relativ egal, wenn ich aber nach längerer Zeit den Quellcode ansehen muss, dann finde ich es hilfreich, wenn ich mich darauf verlassen kann, dass ein übergebenes Objekt nach Rückkehr noch genau so aussieht wie vor dem Aufruf. Deshalb halte ich es grundsätzlich wie Volkard:
    Pointer, wenn die Funktion den Paramter ändert, anderenfalls konstante Referenzen.



  • Ihr tut immer alle rum von wegen Intellisense, Intellisense, Intellisense und seid dann nicht in der Lage, euch den Funktionskopf der auzurufenden Funktion, der ja meist automatisch eingeblendet wird, anzugucken? ohje...

    Meist erkennt man ja schon im Funktionkopf an der Referenz, dem Pointer, oder der const Referenz, ob das Objekt möglicherweise in der Funktion geändert wird, oder nicht geändert wird.



  • Man kann auch seine Funktionsnamen so wählen, dass man sieht, ob die Funktion etwas am übergebenen Objekt ändert. Ich persönlich finde das ja doch übersichtlicher...



  • Bis vor einiger Zeit habe ich es genau so gehalten, ich habe diese Argumente vor Jahren gelesen und fand sie logisch.
    Mittlerweile nutze ich aber auch konstante und nichtkonstante Referenzen, Zeiger sind bei mir eine Garantie dafür, dass sie auch 0 sein dürfen.
    Ist imho auch eine ganz gute Konvention und spart das ständige gegen 0 testen.
    Außerdem muss man davon ausgehen, dass eine Funktion, die nichtkonstante Parameter als Referenz entgegen nimmt, diese auch ändert.



  • It0101 schrieb:

    Ihr tut immer alle rum von wegen Intellisense, Intellisense, Intellisense und seid dann nicht in der Lage, euch den Funktionskopf der auzurufenden Funktion, der ja meist automatisch eingeblendet wird, anzugucken? ohje...

    Meist erkennt man ja schon im Funktionkopf an der Referenz, dem Pointer, oder der const Referenz, ob das Objekt möglicherweise in der Funktion geändert wird, oder nicht geändert wird.

    Für Intellisense müßte ich mit der Maus rumfahren. Naja, ich benutze weder Intellisense noch Debugger, aber das ist ein anderes Thema.
    Den Funktionskopf muß ich nichtmal angucken bei meinem Stil. Ich sehe es schon am Aufruf. Das ist lecker.

    Und daß ich mal einem Zeigerparameter erlauben würde, NULL zu sein, das kommt glaube ich nur in der rekursiven Baumtraversierung vor und sonst gar nirgends. Deswegen brauche ich dafür keine Unterscheidung.



  • yahendrik schrieb:

    Ist imho auch eine ganz gute Konvention und spart das ständige gegen 0 testen.

    Zirkelschluß. Man soll nicht jeden übergebenen Zeiger gegen 0 testen, denn Zeiger bedeuten nicht automatisch, daß der Anwender das Recht hätte, 0 zu übergeben. Was soll auch 0 bedeuten? Daß ich ein Objekt nicht anlegen konnte, daß ich die Ini-Datei nicht lesen konnte? Da ist doch längst eine Exception geflogen. Die Suchfunktionen geben auch nicht mehr 0 zurück, sondern end(). Wie schubse ich mir in C++ eine 0 ins Programm? Und wozu?
    Dein ständiges Geteste entspringt dem Gedanken, Zeiger würden das aussagen, und taugt daher nicht mehr viel, um genau den Gedanken zu begründen.



  • Bei mir kommt das schon hinundwieder mal vor, dass Pointer NULL sind.
    Denn es ist ja oft auch eine Aussage, dass z.B. bestimmte Daten nicht geliefert wurden, oder fehlerhaft geliefert wurden, so dass der Empfänger dann mit NULL auch eine Aussage geliefert bekommt. Klar kann man das auch anders machen, aber NULL langt meist.


Anmelden zum Antworten