Klasse: Überall "this->" vorkleben?
-
Nathan schrieb:
Eben deshalb verwende ich das ja.
m_variable oder this->variable oder gar this->m_variable stört m.M. nach den Lesefluss.Darum nehme ich ja
mVariable-- gleiche Konvention wie für alle andere Variablen, nur beginnend mit "m"
Nathan schrieb:
Da habe ich lieber so ein unauffälliges _.
Neben der Übersehbarkeit würde mich hier stören, dass der Unterstrich bei Operatoren schnell untergeht.
-
Ich schreibe weder "this->", noch haben meine Membervariablen irgendeine Kennung wie "", "m", "m" oder was auch immer. Hab auch noch nie den Sinn darin gesehen. Als ein Argument für ein Präfix wird gerne verwendet, dass Intellisense nach dem Tippen des Präfix nur noch Member anzeigt. Toll, bis ich "m_" geschrieben habe, hat ich mit Intellisense schon den korrekten Member ausgewählt, wenn ich kein Präfix benutze. Weiterhin soll ein Prä- oder Suffix angeblich die Übersichtlichkeit erhöhen, welche Variablen lokal sind und welche zur Klasse gehören. Nun, meine Scopes sind außer bei schlampig programmierter Write-Only-Software klein genug, dass ich die Übersicht sowieso nicht verliere. Dann gibt es noch das Argument der gleichnamigen Parameter bei Konstruktoren und Settern. Letztere hab ich eigentlich sowieso nicht. Die Konstruktorargumente brauche ich genau einmal zum Initialisieren der Member. Daher bekommen auch die Konstruktorargumente den abschließenden Unterstrich und nicht die Member.
-
+1 Michael E., bis auf eins:
Michael E. schrieb:
Die Konstruktorargumente brauche ich genau einmal zum Initialisieren der Member. Daher bekommen auch die Konstruktorargumente den abschließenden Unterstrich und nicht die Member.
Weil ich die Member eigentlich ausschliesslich in der Initialisierungsliste initialisiere, kann ich die Parameter auch genau gleich benennen wie sie.
-
Michael E. schrieb:
...
+1

-
Nexus schrieb:
Nathan schrieb:
Eben deshalb verwende ich das ja.
m_variable oder this->variable oder gar this->m_variable stört m.M. nach den Lesefluss.Darum nehme ich ja
mVariable-- gleiche Konvention wie für alle andere Variablen, nur beginnend mit "m"
Ist ja schön und gut.
Ich nutze die Konvention mit_unterstrichen. Da wäre m_ logischerweise notwendig. m_ ist mir jedoch wieder zuviel Tipparbeit. Also nehme ich nur den Unterstrich. Der sollte allerdings wegen Reserviertheit und so ans Ende. Also _.
Und was hast du gegen:position_.x += speed_ * cur_dir_;? Ja, ok, position_-> bzw. position_. sieht seltsam aus.
Allerdings ist das für mich die beste Alternative.
-
Nathan schrieb:
Also nehme ich nur den Unterstrich. Der sollte allerdings wegen Reserviertheit und so ans Ende.

reserved in any scope:
- Bezeichner, die '__' enthalten.
- Bezeichner, die mit '_' beginnen und dann ein Großbuchstabe folgt.
-reserved in global scope:
3) Globale Bezeichner, die mit '_' beginnen.
-
In Sprachen wie Java, Python, JavaScript,... wuerde nie jemand auf die Idee kommen Member speziell zu kennzeichnen.
Lasst die ungarische Notation bitte endlich sterben. Denn das ist nichts anderes als ein ueberbleibsel aus der C Zeit wo wir ungarische Notation als sinnvoll angesehen haben.
-
C++ wurde entworfen, um Datenabstraktion, objektorientiertes Programmieren und generisches Programmieren zusätzlich zu den traditionellen C-Programmiertechniken mit diesen Einschränkungen zu unterstützen. Es war nicht die Absicht, allen Benutzern einen bestimmten Programmierstil aufzuzwingen.
Bjarne Stroustrup
... wenn jemand gern ungarisch schreibt, soll er ungarisch schreiben. und wenn jemand gern spanisch schreibt, soll er spanisch schreiben ...
-
dd++ schrieb:
...
Es gibt einen Unterschied zwischen Programmierstil und Benamsung.
Und mit ungarisch ist nicht Ungarn sondern UN gemeint.Bjarne Stroustrup schrieb:
No I don't recommend "Hungarian". I regard "Hungarian" (embedding an abbreviated version of a type in a variable name) a technique that can be useful in untyped languages, but is completely unsuitable for a language that supports generic programming and object-oriented programming—both of which emphasize selection of operations based on the type an arguments (known to the language or to the run-time support). In this case, "building the type of an object into names" simply complicates and minimizes abstraction.
-
Live and Let Die
-
Michael E. schrieb:
Nun, meine Scopes sind außer bei schlampig programmierter Write-Only-Software klein genug, dass ich die Übersicht sowieso nicht verliere. Dann gibt es noch das Argument der gleichnamigen Parameter bei Konstruktoren und Settern. Letztere hab ich eigentlich sowieso nicht.
Ist ja schön, dass du alles im Blick hast. Aber scheint auch ein wenig idealistisch; wie weit man ohne Setter kommt, haben wir auch erst kürzlich besprochen. Im Grossen und Ganzen klingt die Argumentation wie "ich brauche kein const, da ich im Blick habe, welche Variablen ich verändern darf".
Aber statt das Offensichtliche zu sagen, nämlich dass es auch ohne m-Präfixe geht, wären Gegenargumente hilfreich. Mir persönlich half m nämlich, Code übersichtlicher zu machen -- ich behaupte nicht, das träfe auf alle Leute zu, aber versuche meine Ansicht nachvollziehbar zu machen. Jedoch gehöre ich auch nicht zu den Leuten, die kategorisch keine Funktionen mit mehr als 3 Parametern oder 15 Zeilen schreiben.
Shade Of Mine schrieb:
In Sprachen wie Java, Python, JavaScript,... wuerde nie jemand auf die Idee kommen Member speziell zu kennzeichnen.
Es liegt in der Natur von Java, auf weniger Ideen zu kommen. Im Gegensatz zu C++ existiert ein etablierter Codestil, was Bezeichner angeht -- natürlich wird dann weniger herumexperimentiert.
Shade Of Mine schrieb:
Lasst die ungarische Notation bitte endlich sterben. Denn das ist nichts anderes als ein ueberbleibsel aus der C Zeit wo wir ungarische Notation als sinnvoll angesehen haben.
Schade, dass ihr wieder mal alles in einen Topf werft. Bei UN ging es darum, Typen kennzuzeichnen. Hier ist aber die Rede von Zugehörigkeit zum Objektzustand. Entsprechend treffen die Nachteile der UN, die ich übrigens schon mehrfach in aller Ausführlichkeit aufgezählt habe, nicht auf das m-Präfix zu.
Bitte die Dinge etwas differenzierter sehen.
-
Nexus schrieb:
Shade Of Mine schrieb:
In Sprachen wie Java, Python, JavaScript,... wuerde nie jemand auf die Idee kommen Member speziell zu kennzeichnen.
Es liegt in der Natur von Java, auf weniger Ideen zu kommen. Im Gegensatz zu C++ existiert ein etablierter Codestil, was Bezeichner angeht -- natürlich wird dann weniger herumexperimentiert.
Es existiert mehr Code in nicht-C++ als in C++.
Es wird mehr in nicht-C++ herumexperimentiert als in C++.Ich rede von jeder modernen Sprache. Egal welche. Ruby? PHP? Python? C#? Go? ... Die Liste ist unendlich lang.
Memberqualifizierung ist ein altes Relikt. In C++ hält man daran fest, wie man vielem alten festhält. Denk einfach darüber nach warum keine einzige moderne Sprache memberqualifzierungen verwendet. Keine einzige.
Es funktioniert nämlich nicht. Du hast soviele Scopes und du suchst dir jetzt einen dieser Scopes (Klasse) aus um die Variablen diesen Scopes zu Kennzeichnen.
Dabei hast du:
Globale Variablen
statische Klassen Variablen
Instanz Variablen
und N Stufen Funktionslokale Variablen (denke an Closures).Wenn wir jetzt lokale Klassen dazu nehmen würden, wird das ganze noch komplexer.
Aber du hast auch ohne dem allen eine inkonsistenz: Template Parameter. Kennzeichnest du diese auch? Sie sind ja Member der Klasse. Und die gibt es auch schon wieder auf Klassen Ebene und N Funktionsebenen.
Du hast jetzt zufällig einen Scope ausgewählt und sagst: das Kennzeichnen der Variablen in diesem Scope ist sinnvoll.
Warum dann nicht in allen Scopes? Warum nur der eine?
-
Shade Of Mine schrieb:
Ich rede von jeder modernen Sprache. Egal welche. Ruby? PHP? Python? C#? Go? ... Die Liste ist unendlich lang. [...] Denk einfach darüber nach warum keine einzige moderne Sprache memberqualifzierungen verwendet. Keine einzige.
Das stimmt so nicht ganz. In Ruby werden Membervariablen mit einem "@" gekennzeichnet. Da ist die Lage aber wiederum anders als in C++ und ich denke auch nicht vergleichbar. Denn in Ruby kann ich Variablen benutzen, ohne sie vorher zu definieren. Daher brauche ich auch ein Mittel, um bei einem vorher unbekannten Namen signalisieren zu können, welchen Scope die Variable hat.
Nexus schrieb:
wie weit man ohne Setter kommt, haben wir auch erst kürzlich besprochen.
Ich habe die Diskussion nur am Rande verfolgt, aber das Fazit war glaube ich, dass reine dumme Setter im engeren Sinne kaum einer benutzt.
Im Grossen und Ganzen klingt die Argumentation wie "ich brauche kein const, da ich im Blick habe, welche Variablen ich verändern darf".
Vorsicht, ganz andere Baustelle. Man kann Klassen und dazugehörige Memberfunktionen so schreiben, dass man die Übersicht über die definierten Variablen behält. Das ist eine lokale Sache und wie ich private Member benenne, geht niemanden außerhalb der Klasse etwas an. Wenn ich aber auf const verzichte, hat das globale Auswirkungen. Objekte werden von einem Ende der Applikation zum anderen Ende übergeben. Hier versuche ich, eine möglichst aussagekräftige Schnittstelle der Klasse zur Außenwelt herzustellen, die mitteilt, ob und wie an die Klasse übergebene Parameter geändert werden können. Die Benennung von Membervariablen ist also eine lokale Angelegenheit innerhalb der Klasse, während die Benutzung von const gerade für die Schnittstelle nach außen in die große weite Welt gebraucht wird.
Aber statt das Offensichtliche zu sagen, nämlich dass es auch ohne m-Präfixe geht, wären Gegenargumente hilfreich.
Präfixe sind potthässlich und Intellisense liefert mir schneller den Namen, den ich suche. Das reicht mir Begründung :p
-
Shade Of Mine schrieb:
Es funktioniert nämlich nicht. Du hast soviele Scopes und du suchst dir jetzt einen dieser Scopes (Klasse) aus um die Variablen diesen Scopes zu Kennzeichnen.
Der Member-Scope ist neben lokalen Variablen aber der am häufigsten benutzte, und nicht willkürlich einer gewählt. Daher ist mit m-Präfixen schon ein grosser Schritt getan. Allerdings hast du recht, konsequenterweise müsste man auch globale Variablen mit
gund statische mitskennzeichnen, allerdings kommen diese ohnehin recht selten vor.Shade Of Mine schrieb:
und N Stufen Funktionslokale Variablen (denke an Closures).
Meinst du Lambda-Ausdrücke? Wo hast du da eine neue Scopekategorie? Sowohl inner- als auch ausserhalb sind für mich lokale Variablen. Nur werden die Funktionen halt zu unterschiedlichen Zeitpunkten aufgerufen. Aber wahrscheinlich habe ich dich hier falsch verstanden...
Shade Of Mine schrieb:
Aber du hast auch ohne dem allen eine inkonsistenz: Template Parameter. Kennzeichnest du diese auch? Sie sind ja Member der Klasse.
Nein, sie sind "Member" des Templates. Sobald du auf der Ebene der Klasse bist, hast du eine Instanziierung, damit gibt es keine Templateparameter mehr. Da dies meist Typen sind, schreibe ich sie in
PascalCase(sofern sie überhaupt länger als ein Buchstabe sind).Michael E. schrieb:
Ich habe die Diskussion nur am Rande verfolgt, aber das Fazit war glaube ich, dass reine dumme Setter im engeren Sinne kaum einer benutzt.
Ja, meist gilt das. Komplett ohne kommt man aber nicht aus. Und teilweise sind auch "dumme" Getter sinnvoll, siehe z.B. sf::Sprite.
Michael E. schrieb:
Die Benennung von Membervariablen ist also eine lokale Angelegenheit innerhalb der Klasse, während die Benutzung von const gerade für die Schnittstelle nach außen in die große weite Welt gebraucht wird.
Das stimmt, aber du kannst das gleiche Argument auf const-qualifizierte lokale Variablen anwenden. Diese sind ebenfalls Implementierungsdetails, trotzdem können sie Fehler innerhalb der Funktion vermeiden -- auch wenn man Funktionen übersichtlich schreibt.
-
Nexus schrieb:
Das stimmt, aber du kannst das gleiche Argument auf const-qualifizierte lokale Variablen anwenden. Diese sind ebenfalls Implementierungsdetails, trotzdem können sie Fehler innerhalb der Funktion vermeiden -- auch wenn man Funktionen übersichtlich schreibt.
Benutzt du const-qualifizierte lokale Variablen?
-
Nexus schrieb:
Michael E. schrieb:
Ich habe die Diskussion nur am Rande verfolgt, aber das Fazit war glaube ich, dass reine dumme Setter im engeren Sinne kaum einer benutzt.
Ja, meist gilt das. Komplett ohne kommt man aber nicht aus. Und teilweise sind auch "dumme" Getter sinnvoll, siehe z.B. sf::Sprite.
Für die berühmten Ausnahmen dieser Regel habe ich das Wort "eigentlich" bemüht. Aber das ist eine ganz andere Baustelle und unabhängig von diesem Thema, da ich auch bei Setterparametern, wenn sie denn mal vorkommen, den abschließenden Unterstrich benutzen kann, statt ihn bei allen Membervariablen zu benutzen.
Das stimmt, aber du kannst das gleiche Argument auf const-qualifizierte lokale Variablen anwenden. Diese sind ebenfalls Implementierungsdetails, trotzdem können sie Fehler innerhalb der Funktion vermeiden -- auch wenn man Funktionen übersichtlich schreibt.
Hier halte ich es wie SeppJ. Benutzt du const für lokale Variablen, die nicht von Anfang an Konstanten sind? Also ich tu das nicht.
-
Michael E. schrieb:
Benutzt du const für lokale Variablen, die nicht von Anfang an Konstanten sind? Also ich tu das nicht.
Also ich benutze manchmal const&-Variablen
ctype<char> const& char_type = use_facet<ctype<char> >(cout.getloc());Allerdings auch nur, weil ich muss.
-
SeppJ schrieb:
Benutzt du const-qualifizierte lokale Variablen?
Ich wollte schon mit "ja" antworten, aber beim Anschauen einiger meiner Codes habe ich festgestellt, dass ich selten lokale Konstanten habe. Wenn, dann vor allem um Literalen einen sinnvollen Namen zu geben.
Konsequenterweise hätte man fast überall
const, auch in ungefährichen Situationen. Dadurch verliert es Aussagekraft und verkompliziert Code. Bei "m" habe ich dieses Gefühl nicht, der Lesefluss wird nicht unterbrochen und Ausdrücke bleiben klein.
-
Nexus schrieb:
Konsequenterweise hätte man fast überall
const, auch in ungefährichen Situationen. Dadurch verliert es Aussagekraft und verkompliziert Code. Bei "m" habe ich dieses Gefühl nicht, der Lesefluss wird nicht unterbrochen und Ausdrücke bleiben klein.Hat auch niemand behauptet. Du hast mit dem const-Vergleich angefangen :p
Edit: Nur, um das nochmal klarzustellen: Ich zwinge niemanden dazu, meine Variante für die beste zu halten. Wer in seinem Code Prä- oder Suffixe verwenden will, soll das meinetwegen tun (vor allem wenn ich den Code nie zu Gesicht bekomme
). Ich habe lediglich geschrieben, warum ich für mich persönlich keinen Vorteil darin sehe.
-
Ich finde es toll, wie hier direkt von einer Qualifizierung für Scopes geredet wird.
Ich bin leider gezwungen, die Membervariablen besonders zu kennzeichnen, weil folgendes nicht geht:class foo { size_t size; public: size_t size(); }Deswegen bekommen die bei mir einen Unterstrich am Ende. Und zwar nur deswegen.