Klasse: Überall "this->" vorkleben?



  • Ich verstehe den Bezug SeppJs Argument zu Jockelx Beitrag nicht, da es nicht um Präfixe sondern Hauptbezeichner geht.

    Also man kann schon p für Point benutzen... aber mit so was würde ich aufpassen. Für Wenigzeiler finde ich es wohl noch okay, aber so häufig kommen die ja auch nicht vor. Als Parameter für Funktionen finde ich es schon schlecht, weil die Funktionen damit ja etwas machen und das auch nicht immer direkt auf der Hand liegt. Und selbst wenn man es sich denken kann, macht man den Nutzen durch den Namen explizit.

    Und einbuchstabige Bezeichner führen eben zum Namenskonflikt, wenn auch alternative Klassennamen in Frage kommen. Bei d denke ich zum Beispiel an double, bei p könnte man an einen Pointer denken. So was wie fis für FileInputStream finde ich wiederum okay, weil man da höchstens an eine Musiknote denkt, das führt wohl nicht zum Konflikt. Dann wiederum könnte der Code-Einseher sich trotzdem wundern. Da ist ein voller Bezeichner einfach klarer. Kurze Bezeichner sparen nur etwas Tipparbeit, aber da ich sowieso ding vorgeschlagen bekomme, sobald ich d eingebe, ist das Argument für mich nicht ziemlich schwach.

    rationalerCoder:
    Falls ich denke, dass es hilft, wähle ich übrigens wirklich Bezeichner, die so lang wie Deine sind und auch viel aussagen. Natürlich nicht für solche trivialen Fälle, aber in komplexeren Situationen kann das wirklich helfen.



  • Ich dachte es geht sowieso nur um sehr lokale Objekte. Natürlich ist das als Funktionsparameter Mist.
    Aber ich halt mich da jetzt raus.
    Glaube nicht, dass das zu was führt.


  • Mod

    Jockelx schrieb:

    Ich dachte es geht sowieso nur um sehr lokale Objekte. Natürlich ist das als Funktionsparameter Mist.
    Aber ich halt mich da jetzt raus.
    Glaube nicht, dass das zu was führt.

    Ich habe bewusst etwas übertrieben. Natürlich ist folgendes ok:

    for(Point p ...) 
     { 2-3 Zeilen}
    

    Das wird aber ganz schnell schlimm, wenn es in der nächsten Eskalationsstufe zu

    class Foo
    {
      Point p, p2;
      double d;
      Ding dd;
    };
    

    wird. Das ist dann schon richtig übel. Wenn ich Code nicht nur für mich selber schreibe, benutze ich daher selbst bei Kleinstfunktionen halbwegs aussagekräftige Namen. Schon mit 4-6 Zeichen kann man Code um so vieles lesbarer machen:

    for (int line ...)
     for (int column  ...)
    // anstatt
    for (int i ...)
     for (int j ...}
    

    Schon besteht keine Gefahr mehr, dass diese Variablen jemals aus Unkenntnis falsch benutzt werden, egal wie lang der Code in 10 Jahren ist, nachdem er durch 15 Hände gewandert ist. Kosten: Praktisch 0. Tippgeschwindigkeit ist bei mir (und wohl jedem anderen) nicht der begrenzende Faktor beim Programmieren.



  • Die einzigen Bezeichner, die ein Buchstabe lang sein können, sind immer noch x und y.



  • SeppJ schrieb:

    Tippgeschwindigkeit ist bei mir (und wohl jedem anderen) nicht der begrenzende Faktor beim Programmieren.

    Das stimmt zwar, aber Code mit kurzen Bezeichnern ist übersichtlicher. Schneller zu verstehen.

    Ich finde deinen ökonomischen und ökologischen Code übersichtlicher wie meinen Buchstabensalat (ich habe dort eine Klammer weggelassen und es ist keinem aufgefallen).

    Und logisch skaliert "d" nicht auf Funktionen mit mehreren Variablen. Aber dann verwende ich auch nicht "d", sondern einen sprechenden Namen (was "ding" ausschliest, weil genauso nichtssagend).

    Für alles ausser lokalen Variablen in trivialen Funktionen, also insbesondere Member, sind einbuchstabige Namen Quatsch.



  • rationaler coder schrieb:

    SeppJ schrieb:

    <getrolle>

    Achso, du schreibst lieber

    const MeinIntTypedef anfangsWertFuerDieSchleife = ZAHL_NULL;
    ///...
    

    statt

    for (int i=0; i<100; ++i)
    

    Es gibt noch viel zwischen den Extremen. In vielen Fällen sind kurze, aber dennoch lesbare Bezeichner ausreichend. Wobei ich durchaus lange Bezeichner wähle wenn dies zur Beschreibung der Aufgabe dieser Variable nötig ist (da würde mir ein Präfix aber auch nichts helfen).

    So finde ich die Aufgabe auch wesentlich wichtiger als deren Datentyp. Nehmen wir ein Beispiel: "std::size_t anzahlStudenten". Es ist hier eigentlich egal was für ein Typ diese Variable hat, zum lesen des Codes ist die Aufgabe viel wichtiger. Und die kann man hier direkt aus dem Namen ableiten. Und häufig sagt der Kontext in dem die Variable steht schon genügend aus um diese weiter abzukürzen (z.B. auf "anzahl").

    Man liest Code wesentlich häufiger als man ihn schreibt. Und zum Lesen ist der Sinn, selten der Typ relevant (gute IDEs liefern einen ohnehin den Typ spätestens wenn man die Maus über den Namen hält). Und wenn man zudem versucht Funktionen eher klein zu halten, kann man den Typ auch notfalls recht schnell herausfinden wenn er wichtig ist.

    Ganz davon abgesehen ändere ich eher den Datentyp als die Aufgabe einer Variable. Und nicht jede IDE hat Refactoring-Werkzeuge zum umbenennen... (leider nicht).



  • Shade Of Mine schrieb:

    Du erzeugst damit neue Scopes. Warum kennzeichnest du diese nicht?

    Weil ich dadurch keinen Vorteil sehe. Es reicht, die Scopes kennzuzeichnen, deren Unterscheidung am meisten bringt: Member und lokale Variablen. Weil man keine this-> vergisst und direkt sieht, wenn der Objektstatus verändert wird. Zum Beispiel hatte ich auch schon Memberfunktionen, in denen gar keine Variable mit m -Präfix vorkommt. So sehe ich recht schnell, dass ich hier auch eine globale oder statische Funktion verwenden kann.

    Nathan schrieb:

    Die einzigen Bezeichner, die ein Buchstabe lang sein können, sind immer noch x und y.

    Manchmal sind kurze Variablen aussagekräftig genug, weil sie im jeweiligen Bereich etabliert sind. Beispiele sind x, y, z, vx, t, phi, etc.

    Ansonsten gilt: Wie kurz ein Bezeichner sein darf, hängt von dessen Lokalität ab. Je grösser der Scope, desto aussagekräftiger muss die Variable sein. Bei Lambda-Funktionen nehme ich ab und zu sehr kurze Bezeichner, um die kompakte Definition nicht unnötig aufzublähen. Schade, dass wir keine polymorphen Lambdas haben 😞



  • Warum haben dann Memberfunktionen keinen Prefix?
    Gilt diese Argumentation denn nicht 1:1 auch fuer Funktionen?



  • Nathan schrieb:

    Die einzigen Bezeichner, die ein Buchstabe lang sein können, sind immer noch x und y.

    Das könnn noch etliche mehr sein:

    //implemented after Rosenberg et.all "A smart way to optimize the Bar problem", formula (16)
    return a*b+C/phi*epsilon_sqrt(epsilon/exp(gamma));
    

    in der Tat wäre es an der Stelle verwirrend, irgendwelche anderen Bezeichner als die im Paper zu verwenden.



  • Ich habe mich wohl sehr unklar ausgedrückt.
    Natürlich sind kleine Bezeichner in Ordnung, wenn der Kontext ihnen eine eindeutige Bezeichnung gibt.



  • Shade Of Mine schrieb:

    Warum haben dann Memberfunktionen keinen Prefix?
    Gilt diese Argumentation denn nicht 1:1 auch fuer Funktionen?

    Ein Teil trifft auf Funktionen zu, nicht alles.

    Namenskollisionen sind sehr selten (bei Variablen hat man sie schon in fast jedem Setter, teilweise auch Konstruktor). Tendenziell werden innerhalb der Klasse mehr Memberfunktionen als globale Funktionen aufgerufen. Viele globale Funktionsaufrufe sind durch Namensräume qualifiziert.



  • Nexus schrieb:

    Shade Of Mine schrieb:

    Warum haben dann Memberfunktionen keinen Prefix?
    Gilt diese Argumentation denn nicht 1:1 auch fuer Funktionen?

    Ein Teil trifft auf Funktionen zu, nicht alles.

    Was genau trifft auf Funktionen denn nicht zu?
    Bedenke dabei: lokale Variablen sind auf den 1. Blick erkennbar (die Definition der Variable ist ja direkt in der Funktion sichtbar), der Unterschied Memberfunktion oder globale Funktion aber nicht.

    Und Namensraumqualifizierungen sollten nicht oft vorkommen - wir haben using dafuer.



  • Shade Of Mine schrieb:

    Was genau trifft auf Funktionen denn nicht zu?

    Das steht im zweiten Teil meines Posts...

    Shade Of Mine schrieb:

    Und Namensraumqualifizierungen sollten nicht oft vorkommen - wir haben using dafuer.

    Warum nicht? Ich verwende die using -Deklaration und -Direktive sehr selten.



  • Also ist Namenskollision das einzige Argument fürs Membervariablen Kennzeichnen?

    Ich bin mir nicht sicher ob wirklich mehr Memberfunktionen als externe Funktionen verwendet werden. Wenn ich bei meinen Codes so durchschaue, werden eher selten Memberfunktionen aufgerufen.

    Ich will nicht über using Sprechen, aber wenn du in deinem::code::dauernd::doppelpunkte::stehen::hast::dann::könnte::das::schwer::zu::lesen::sein. 😉



  • Es geht darum, potenzielle Zugriffe auf das Objekt schneller zu erkennen. Bei Variablen wird das durch m -Präfixe möglich. Bei Funktionen kann ich diejenigen ausschliessen, die durch Namensräume qualifiziert sind. Übrig bleiben dann vor allem Memberfunktionen und ein paar globale Funktionen, bei denen ich dann genauer hinschaue. Ich glaube du verstehst die Absicht dahinter falsch: Ich will nicht sämtliche Scopes eindeutig klassifizieren, sondern die meisten Fälle im Bezug auf Objekt-Zugriffe abdecken. Mein System ist nicht die totale Lösung, aber es ist meiner Meinung nach ein guter Kompromiss zwischen Aufwand und Ertrag.

    Ich habe recht selten verschachtelte Namensräume. Es gibt ja auch die Möglichkeit, lange Namensraumqualifizierer mittels eines Alias kürzer zu machen. Sowas wie std:: schreibe ich eigentlich immer hin, ausser ich möchte tatsächlich ADL verwenden, z.B. bei swap() .



  • Nexus schrieb:

    Es geht darum, potenzielle Zugriffe auf das Objekt schneller zu erkennen. Bei Variablen wird das durch m -Präfixe möglich. Bei Funktionen kann ich diejenigen ausschliessen, die durch Namensräume qualifiziert sind. Übrig bleiben dann vor allem Memberfunktionen und ein paar globale Funktionen, bei denen ich dann genauer hinschaue. Ich glaube du verstehst die Absicht dahinter falsch: Ich will nicht sämtliche Scopes eindeutig klassifizieren, sondern die meisten Fälle im Bezug auf Objekt-Zugriffe abdecken. Mein System ist nicht die totale Lösung, aber es ist meiner Meinung nach ein guter Kompromiss zwischen Aufwand und Ertrag.

    Und ich zeige dir inkonsistenz auf.

    Warum gilt deine Argumentation für Funktionen nicht?

    Du kennzeichnest die Member weil du es so gelernt hast. Habe ich auch gemacht - habe auch viel Zeit reingesteckt wie man die Sachen am besten Kennzeichnet. Aber im endeffekt ist jede Kennzeichnung nur random.



  • Shade Of Mine schrieb:

    Und ich zeige dir inkonsistenz auf.

    Das musst du mir nicht aufzeigen, das bringt "Ich will nicht sämtliche Scopes eindeutig klassifizieren" eben mit sich 🙂

    Ich glaube, wir haben mittlerweile alles diskutiert. Ich kann ja mal wieder ein kleines Projekt ohne m -Präfixe versuchen und schauen, wie lange es geht, bis mich das ganze aufregt 😉



  • Nexus schrieb:

    Shade Of Mine schrieb:

    Und ich zeige dir inkonsistenz auf.

    Das musst du mir nicht aufzeigen, das bringt "Ich will nicht sämtliche Scopes eindeutig klassifizieren" eben mit sich 🙂

    Davon rede ich nicht. Ich rede von Funktionen und Variablen. Beide im selben Scope. Keine unterschiedlichen.



  • Ich habe versucht klarzumachen, wieso ich Variablen kennzeichne und Funktionen nicht. Das ist nicht random (Willkür), lies nochmal die Begründung. Du bist der Ansicht, nur beides oder nichts wären gangbare Wege -- okay. Sehen wir halt anders, ich werde jedenfalls nicht nochmals jeden Punkt einzeln durchdiskutieren.



  • Nexus schrieb:

    Du bist der Ansicht, nur beides oder nichts wären gangbare Wege

    Nein, bin ich nicht.


Anmelden zum Antworten