Coding Stil: auto vs auto*



  • Hallo zusammen,

    ich habe mich in letzter Zeit gefragt, was wohl der bessere Stil ist, bzw. was für mich einfacher zu lesen ist, wenn ich mir meinen Code in einem Jahr nochmal anschaue.

    auto p = new foo();
    //oder
    auto* p = new foo();
    

    Durch new wird hier ja noch angezeigt, dass es sich eindeutig um einen Pointer handeln muss, aber gibt ja auch andere Konstrukte wie:

    auto p = getPointer();
    //vs.
    auto* p = getPointer();
    

    Wenn der Getter dann den Pointer nicht mehr im Namen hat, ist das Ganze nicht mehr so schnell ersichtlich.

    Im Moment nutze ich die jeweils erste Variante, frei nach der Meinung, dass wenn ich den Typ schon automatisch bestimmen lasse, dann auch komplett. Dann muss ich auch nichts ändern, wenn sich irgendwo das Interface ändert und anstelle eines Raw Pointers mal irgendwo ein Smart Pointer raus kommt.
    Ich frage mich nur, ob ich das später noch genau so sehe?

    Wie handhabt ihr das? Hab ich einen wichtigen Punkt übersehen?


  • Mod

    Hab ich einen wichtigen Punkt übersehen?

    Option C: Keine rohen Pointer benutzen.



  • SeppJ schrieb:

    Option C: Keine rohen Pointer benutzen.

    Es gibt aber tatsächlich Bibliotheken, bei denen man kaum drum rum kommt. Ich arbeite im Moment z.B. mit wxWidgets, die ihre Speicherverwaltung intern machen und den auch freigeben, man aber den Speicher selbst mit new reservieren muss.



  • SeppJ schrieb:

    Option C: Keine rohen Pointer benutzen.

    *Keine rohen, besitzenden Pointer benutzen. 🙂

    auto p1 = std::make_unique< int >();
    auto p2 = std::strchr( "Hello World!", ' ' );
    

  • Mod

    Wenn von dem lokalen Code, der p verwendet, ersichtlich ist, dass p ein Zeiger sein muss, dann sollte der Deklarator das auch forcieren. Sollte jemand den Rückgabetyp ändern, dann wird die resultierende Fehlermeldung so am klarsten sein (+- quality of diagnostics).

    Wenn der Code generisch genug ist, auch mit Smart-Pointern o.ä. zu funktionieren (bspw. via pointer_traits ), sollte der Deklarator entsprechend generisch sein.

    Edit: Wobei das eigentlich gar keinen Sinn macht. Ein Verweis auf ein Objekt sollte immer entweder ein roher Zeiger oder eine Referenz sein, ein Smart Pointer als Rückgabetyp deutet ja auf einen Besitzwechsel/eine Besitzerweiterung hin, und ein Code kann selten sowohl rohe als auch smart pointer gleichermaßen behandeln.


Anmelden zum Antworten