Pointer oder Referenzen bei Übergabeparameter?



  • Was ist in C++ im allgemeinen eigentlich üblicher bei der Übergabe einer Variablen vom Typ einer Klasse: Die Übergabe per Referenz oder per Pointer?

    void function (const AnyClass & classobject); //So?
    
    void function (const AnyClass * classobject); //Oder so?
    


  • PointRef schrieb:

    Was ist in C++ im allgemeinen eigentlich üblicher bei der Übergabe einer Variablen vom Typ einer Klasse: Die Übergabe per Referenz oder per Pointer?

    void function (const AnyClass & classobject); //So?
    
    void function (const AnyClass * classobject); //Oder so?
    

    bei const immer referenz.
    bei nonconst scheiden sich die geister. da nehme ich zeiger. es gibt aber viele, die meinen, referenzen seien irgendwie sicherer oder besser (zu viel java gegessen!) und nehmen referenzen wannimmer gerade noch erlaubt. läßt sich bei nonconst nicht klären, was besser ist, weil es zu selten vorkommt. gute funktionen haben nämlich das zu ändernde objekt als subjekt, also als *this übergeben, weswegen die nonconst-übergabe praktisch nicht vorkommt und die stilfrage hier mangels sinnvoller untersuchbarer codefragmente nicht entscheidbar ist.



  • volkard schrieb:

    bei const immer referenz.

    Wieso ist das so? In welchem Zusammenhang steht die Frage nach const oder nicht-const mit der Frage nach Referenz oder Pointer?

    Zur Idee, dass Referenzen besser wären: Man muss sie zumindest nicht auf Gültigkeit (if (reference)) überprüfen.



  • Reicht doch schon oder? Du kannst kein NULL Objekt übergeben. Damit kannst du dir etliche Abfragen und Fehlerquellen sparen.

    grüße



  • Hallo

    Also ich mach es auch wie Volkard, weil ich bei Funktion, die ein Parameter ändert dann immer & davorschreiben muss und somit gearnt bin: Aha, die Funktion ändert den Parameter. Bei const brauch ich aber nicht zu wissen, was in der Funktion passiert und ich nutze deswegen Referenzen.

    chrische



  • Wenn du allerdings generell mit Pointern arbeitest (die du mit new angelegt hast) ist es aber genau umgekehrt. Da kannst du bei einer Übergabe per Pointer den Namen direkt schreiben, während du bei einer Übergabe per Referenz *wert schreiben musst.

    Ich habe übrigens eine Möglichkeit gefunden, wo Referenzen durchaus ungültig sein können:

    void f (int &i);
    
    int main ()
    {
        int *i=NULL;
    
        f (*i); //Laufzeitfehler!
    }
    

    Dcoch ich würde nochmal gern die Begründung von volkard hören, wieso bei konstanten Parametern immer Referenzen zu nehmen sind, während das bei nicht konstanten Parametern an sich Geschmackssache ist. Ist es so, wie chrische5 gesagt hat, dass man dann durch das & daran erinnert wird, dass die Funktion vielleicht etwas ändert?



  • Gibt es keine Referenzbeispiele (pun not intended) aus dem C++-Standard?



  • Ich persönlich übergebe Objekte immer dann als Referenz, wenn sie existieren müssen, d.h. keine Nullzeiger erlaubt sind. Mit const/nicht-const hat das allerdings gar nichts zu tun. Man kann durchaus Zeiger auf konstante Objekte brauchen, z.B. für optionale Parameter als Alternative zu einer Funktionsüberladung.



  • chrische5 schrieb:

    ... weil ich bei Funktion, die ein Parameter ändert dann immer & davorschreiben muss und somit gearnt bin: Aha, die Funktion ändert den Parameter.

    Ich kann diesen Grund nicht nachvollziehen. Ich bin der Ansicht: Wenn man eine Funktion aufruft, dann sollte man sowieso unbedingt wissen, was sie tut. Und wenn man das weiß, dann weiß man auch, ob sie Parameter verändert. Diese Warnsymbol-Argumentation (gibt es ja auch in anderen Bereichen, z.B. diese Regel, SYMBOLISCHE_KONSTANTEN groß zu schreiben) kann ich daher generell nicht nachvollziehen.



  • chrische5 schrieb:

    Also ich mach es auch wie Volkard, weil ich bei Funktion, die ein Parameter ändert dann immer & davorschreiben muss und somit gearnt bin: Aha, die Funktion ändert den Parameter.

    Darum gibt es ja das kleine aber feine Schlüsselwort "const" 😉 Wenn ein "const" vor dem Parameter steht, wird dieser nicht verändert - kann man ja auch gar nicht.



  • Zu dem Beispiel mit der ungültigen Referenz
    Die gülitgkeit von Parametern wird bei Referenzen vom Aufrufer erledigt und bei einem Pointer Parameter von der Funktion.

    Nur so meine Faustregel



  • PointRef schrieb:

    volkard schrieb:

    bei const immer referenz.

    Wieso ist das so? In welchem Zusammenhang steht die Frage nach const oder nicht-const mit der Frage nach Referenz oder Pointer?

    ich hab keinen unterschied zwischen print(student)//by val und print(strudent)//by const ref.

    Zur Idee, dass Referenzen besser wären: Man muss sie zumindest nicht auf Gültigkeit (if (reference)) überprüfen.

    das halte ich für veraltet. zugriffe auf nullzeiger passieren nicht und dagegen prüfen ist zeitverschwendung.



  • templäd schrieb:

    und bei einem Pointer Parameter von der Funktion.

    wozu das denn? lass die kiste doch abschmieren, wenn du strlen(0) berechnen willst. und überhaupt, was sollte denn das ergebnis sein? -1? und was willste bei strcpy(0,"hallo") machen? nix? dann wir der nachste, der die 0 benutzt, das roblem haben. lass den rechner ruhig in die schutzverletzung laufen und gut ist's.



  • Meiner Meinung nach tritt das Problem ja nur bei Operator Überladung auf.
    Eine "gute" Funktion/Methode sollte nicht einen Übergabeparameter verändern dürfen. Ergebnisse sollten nur mit return zurückgegeben werden.



  • 1310-Logik schrieb:

    Meiner Meinung nach tritt das Problem ja nur bei Operator Überladung auf.

    bei operatoren ist aber wiederum sonnenklar,m ob zeiger oder referenz.

    Eine "gute" Funktion/Methode sollte nicht einen Übergabeparameter verändern dürfen. Ergebnisse sollten nur mit return zurückgegeben werden.

    jo. und zweimal im jahr findet sich ne unwichtige ausnahme.



  • Neku schrieb:

    chrische5 schrieb:

    Also ich mach es auch wie Volkard, weil ich bei Funktion, die ein Parameter ändert dann immer & davorschreiben muss und somit gearnt bin: Aha, die Funktion ändert den Parameter.

    Darum gibt es ja das kleine aber feine Schlüsselwort "const" 😉 Wenn ein "const" vor dem Parameter steht, wird dieser nicht verändert - kann man ja auch gar nicht.

    Wäre ich paranoid oder bösartig, könnte ich das const mit const_cast einfach wegcasten und fröhlich das Objekt verändern :p 😉



  • GPC schrieb:

    Neku schrieb:

    chrische5 schrieb:

    Also ich mach es auch wie Volkard, weil ich bei Funktion, die ein Parameter ändert dann immer & davorschreiben muss und somit gearnt bin: Aha, die Funktion ändert den Parameter.

    Darum gibt es ja das kleine aber feine Schlüsselwort "const" 😉 Wenn ein "const" vor dem Parameter steht, wird dieser nicht verändert - kann man ja auch gar nicht.

    Wäre ich paranoid oder bösartig, könnte ich das const mit const_cast einfach wegcasten und fröhlich das Objekt verändern :p 😉

    Wieso braucht eine Programmiersprache eigentlich ne "Kindersicherung"? Man sollte meinen, es seien Vernünftige Menschen am Werk.. :p 😉



  • Ich halt es so:

    Referenzen da wo geht,
    Pointer da wo man referenzen nicht nutzen kann.

    Faelle wo Referenzen nicht so geeignet sind:

    - wenn man nen explizieten nicht definiert / nicht gueltig Wert braucht ... (NULL Pointer)
    - Wenn ich extensiv caste. Geht zwar prinizipiell auch mit referenzen, aber gefuehlsmaessig nehm ich da doch lieber pointer. (denk mal haengt eher damit zusammen das man bei nem logischen cast gern mal nen ungueltigkeitswert haett, also eher siehe punkt 1)
    - referenzen kann man ned in standardcontainer pappen ... da muss man pointer nehmen ....

    Ciao ...



  • Wo ich keinen Weg mit Referenzen sehe: bei der Behandlung polymorpher Objekte



  • 1310-Logik schrieb:

    Eine "gute" Funktion/Methode sollte nicht einen Übergabeparameter verändern dürfen. Ergebnisse sollten nur mit return zurückgegeben werden.

    Das halte ich für nicht konsequent umsetzbar. Was machst Du, wenn eine Methode mehrere Parameter ändern muss?

    Ich halte es so, wie viele bereits gesagt haben:
    - wenn nichts geändert wird: const-Referenz
    - wenn nichts geändert wird, aber eine Referenz nicht geht, aus welchem Grund auch immer: const-Pointer auf const-Daten
    - wenn geändert wird: Referenz
    - wenn geändert wird, aber Referenz nicht geht, aus welchem Grund auch immer: Pointer (wobei da noch zu überlegen ist, ob der Pointer const deklariert wird und nur die Daten nicht const sind)

    Wobei ich alle Fälle schon einsetzen musste.

    1310-Logik schrieb:

    Wieso braucht eine Programmiersprache eigentlich ne "Kindersicherung"? Man sollte meinen, es seien Vernünftige Menschen am Werk..

    Ich sehe das const eher als eine Hilfestellung, die dem Benutzer einer Methode sagt, diese Parameter werden von der Funktion geändert und diese eben nicht. Umgehen kann man alles, auch an eine private-deklarierte Klassenvariable kommt man von außen heran, wenn man will.


Log in to reply