Zeiger als Parameter von Funktionen



  • Bei Ersterem würde ich erwarten dass hier kopiert wird.

    Ja, aber da du gesunden Menschenverstand hast, wirst du immer zuerst die Dokumentation lesen, wo groß und fett steht, wie das ganze Implementiert wurde, um Missverständnisse zu vermeiden.



  • edit: Mist



  • daddy_felix schrieb:

    Ethon schrieb:

    Welche Nachteile bitte?

    dass du immer auf NULL prüfen musst?

    Muss ich das? In den allermeisten Fällen wird ein nullptr absichtlich übergeben und wer absichtlich eine API falls benutzt ... naja.

    Beispielsweise die hohe Fehleranfälligkeit durch falsche Initialisierung.

    Ich kann einen Pointer genau wie eine Referenz verwenden, mit syntaktischen Unterschieden.



  • Sone schrieb:

    Nathan schrieb:

    Naja, ich nutze immer noch rohe Zeiger.
    Wenn ich bspw. eine Klasse habe, die einen änderbaren, ab und zu auch mal ungültigen Verweis auf eine andere Klasse braucht.

    Ja, da wirst du zu sowas gezwungen. Das ist in Ordnung.

    Aber selbst da nutze ich zur Initialisierung eine Referenz, damit mir kein DAU da einen nullptr reinfrimmelt...



  • Nathan schrieb:

    Sone schrieb:

    Nathan schrieb:

    Naja, ich nutze immer noch rohe Zeiger.
    Wenn ich bspw. eine Klasse habe, die einen änderbaren, ab und zu auch mal ungültigen Verweis auf eine andere Klasse braucht.

    Ja, da wirst du zu sowas gezwungen. Das ist in Ordnung.

    Aber selbst da nutze ich zur Initialisierung eine Referenz, damit mir kein DAU da einen nullptr reinfrimmelt...

    Natürlich. Oder könnte der User deiner Klasse vielleicht denken, es wird kopiert? Dann nimm doch lieber Zeiger. Unsicherer, aber Hauptsache keine falschen Implikationen...



  • Ethon schrieb:

    daddy_felix schrieb:

    dass du immer auf NULL prüfen musst?

    Muss ich das? In den allermeisten Fällen wird ein nullptr absichtlich übergeben und wer absichtlich eine API falls benutzt ... naja.

    lol

    wenn du wüsstest, wie oft wir uns hier mit Nullpointern rumschlagen, die eben *nicht* absichtlich übergeben wurden...

    void MyFunction(std::string* str)
    {
      // mach was mit str ohne Überprüfung
    }
    
    std::string* myString = GetSomeString();
    MyFunction(myString);
    

    Wenn jetzt GetSomeString() aus irgendeinem Grund NULL zurückliefert, knallt es.



  • Ethon schrieb:

    daddy_felix schrieb:

    Ethon schrieb:

    Welche Nachteile bitte?

    dass du immer auf NULL prüfen musst?

    Muss ich das? In den allermeisten Fällen wird ein nullptr absichtlich übergeben und wer absichtlich eine API falls benutzt ... naja.

    Der hat seinen gesunden Menschenverstand nicht benutzt und nicht in die Doku geschaut, s.o.

    Ethon schrieb:

    Beispielsweise die hohe Fehleranfälligkeit durch falsche Initialisierung.

    Ich kann einen Pointer genau wie eine Referenz verwenden, mit syntaktischen Unterschieden.

    Ich kann auch ein Fahrrad wie ein Auto verwenden, mit Straßenverkehrsordnungsspezifischen Unterschieden.



  • daddy_felix schrieb:

    Ethon schrieb:

    daddy_felix schrieb:

    dass du immer auf NULL prüfen musst?

    Muss ich das? In den allermeisten Fällen wird ein nullptr absichtlich übergeben und wer absichtlich eine API falls benutzt ... naja.

    lol

    wenn du wüsstest, wie oft wir uns hier mit Nullpointern rumschlagen, die eben *nicht* absichtlich übergeben wurden...

    void MyFunction(std::string* str)
    {
      // mach was mit str ohne Überprüfung
    }
    
    std::string* myString = GetSomeString();
    MyFunction(myString);
    

    Wenn jetzt GetSomeString() aus irgendeinem Grund NULL zurückliefert, knallt es.

    Hier sehe ich den Fehler aber bei GetSomeString() 😉
    Bei mir entstehen keine nullptr, die nicht absichtlich erzeugt wurden.

    Wenn die Funktion fehlschlagen kann, dann würde ich eine Exception werfen.
    Wenn es normal ist dass Funktion einen ungültigen Wert zurückgeben kann, dann wäre das je nach Kontext ein Iterator oder boost::optional.

    Sone schrieb:

    Ethon schrieb:

    daddy_felix schrieb:

    Ethon schrieb:

    Welche Nachteile bitte?

    dass du immer auf NULL prüfen musst?

    Muss ich das? In den allermeisten Fällen wird ein nullptr absichtlich übergeben und wer absichtlich eine API falls benutzt ... naja.

    Der hat seinen gesunden Menschenverstand nicht benutzt und nicht in die Doku geschaut, s.o.

    Ethon schrieb:

    Beispielsweise die hohe Fehleranfälligkeit durch falsche Initialisierung.

    Ich kann einen Pointer genau wie eine Referenz verwenden, mit syntaktischen Unterschieden.

    Ich kann auch ein Fahrrad wie ein Auto verwenden, mit Straßenverkehrsordnungsspezifischen Unterschieden.

    1. Es gibt immer Leute, die nicht in die Doku schauen. Trotzdem ist das ein schwer auffindbarer Bug, der so leicht zu vermeiden ist.
    2. Nicht alles was hinkt ist ein Vergleich 😉 ... sorry, aber eine Referenz und ein Pointer unterscheiden sich nur geringfügig.



  • sorry, aber eine Referenz und ein Pointer unterscheiden sich nur geringfügig.

    Jein. Ein Zeiger speichert eine Adresse. Eine Referenz referenziert ein Objekt. Wo ist da, ganz technisch, die Gemeinsamkeit?
    Klar, ihr Zweck ist letzten Endes ähnlich.

    Edit: Nein, auch das nicht, jedenfalls nicht immer.



  • Ethon schrieb:

    Wenn die Funktion fehlschlagen kann, dann würde ich eine Exception werfen.

    ohoh, das ist aber gefährlich. Woher soll denn der DAU wissen, dass deine Funktion fehlschlagen könnte und dann eine Exception wirft?

    Sag jetzt bitte nicht "Doku", denn

    Ethon schrieb:

    1. Es gibt immer Leute, die nicht in die Doku schauen.



  • Sone schrieb:

    sorry, aber eine Referenz und ein Pointer unterscheiden sich nur geringfügig.

    Jein. Ein Zeiger speichert eine Adresse. Eine Referenz referenziert ein Objekt. Wo ist da, ganz technisch, die Gemeinsamkeit?
    Klar, ihr Zweck ist letzten Endes sehr ähnlich.

    Du weißt schon dass du auch bei Zeigern von Referenzierung/Dereferenzierung sprichst oder?

    Eine Referenz verhält sich syntaktisch wie ein bestehendes Objekt (wurden sie deswegen nicht sogar eingeführt? Wegen der Syntax der Operatorenüberladung ?) und sie muss zwingend mit einem Objekt initialisiert werden. Ansonsten sind sie gleich.
    Im Compileroutput ist eine Referenz nicht von einem Zeiger zu unterscheiden, das ist reiner Syntaxzucker.

    daddy_felix schrieb:

    Ethon schrieb:

    Wenn die Funktion fehlschlagen kann, dann würde ich eine Exception werfen.

    ohoh, das ist aber gefährlich. Woher soll denn der DAU wissen, dass deine Funktion fehlschlagen könnte und dann eine Exception wirft?

    Sag jetzt bitte nicht "Doku", denn

    Ethon schrieb:

    1. Es gibt immer Leute, die nicht in die Doku schauen.

    Dann wird der Exception vermutlich bis in die Main durchrauschen und es gibt eine schöne Fehlermeldung und der Nutzer weiß es. 😉
    Im meinem Fall wäre es eine Referenz, die mitten in den Stack zeigt. Das ist ganz böse.



  • Ethon schrieb:

    Eine Referenz verhält sich syntaktisch wie ein bestehendes Objekt (wurden sie deswegen nicht sogar eingeführt? Wegen der Syntax der Operatorenüberladung ?) und sie muss zwingend mit einem Objekt initialisiert werden. Ansonsten sind sie gleich.
    Im Compileroutput ist eine Referenz nicht von einem Zeiger zu unterscheiden, das ist reiner Syntaxzucker.

    Der Compileroutput interssiert mich meistens nicht. Wenn er mich interessieren würde, kann ich auch gleich wieder C programmieren. In C++ ist eh fast alles syntaktischer Zucker.
    Referenzen unterscheiden sich nicht nur syntaktisch sondern auch semantisch doch recht erheblich voneinander.
    Referenzen stellen über ihre gesamte Lebensdauer ein Alias auf ein Objekt dar. Zeiger können während ihrer Lebensdauer auf viele verschiedene Objekte, auf ein definiert ungültiges Objekt, oder auf irgendetwas zeigen. Ich finde, das sind genügend Unterschiede.


Anmelden zum Antworten