Thema: "Naming Conventions" (mein Tip!)
-
thinux schrieb:
wow, scheint doch ein interessantes thema zu sein? (über 50 comments an einem tag, wenn auch nicht alle so geistreich...)
also, vieleicht ligt es ja daran, dass ich generell beim arbeiten recht ordentlich und struckturiert vorgehe...
ich für meinen teil muss sagen, dass es besonders für eine spätere überarbeitung, fehlersuche oder dokumentation meiner projekte sehr hilfreich ist, wenn man "von weitem" erkennt worum es sich handelt:Wo wir beim Verarbeiten sind: was machst du wenn erkennst, dass die Ergebnisse deines Programmes nicht genau genug sind, und du deine Variablen alle von float auf double umstellen musst? Durch den ganzen Quelltext gehen und alle "f"-Prefixe durch "d"-Prefixe ersetzen? Oder wenn du statt Comboboxen doch lieber ein List-Element einsetzen willst? alle cmb durch lst ersetzen?
-
thinux schrieb:
w
ein guter stiel beim programmieren ist wie schönschrift bei gedicht und gehört somit einfach dazuDu bist offtopic, hier geht's um Stil, nicht um Stiel.
-
1310-Logik schrieb:
Nein nur für Members, denn die Übergabeparameter für Members brauch ich nur in den Konstruktoren und Accessoren, die Membervariable auch in x anderen Methoden der Klasse. Da spar ich mir die Prä/Postfixe dann.
und wenn du eine neue member einbaust die du nutzen möchtest, prüfst du dann in der implementierungsdatei ob der variablenname schon in funktionen benutzt wurde und änderst den dort oder wie ist der workflow?
-
unkreativ`` schrieb:
Ich interpretier da gar nichts hinein und hab auch nichts von IDEs erwähnt in diesem Kontext. Damit wollte ich nur festhalten, dass du andere Ansätze für - ich sag mal - Typbeschreibung mit dem Argument, gibt es bereits "abschmetterst", was auf mich nicht gerade offen gegenüber Innovationen wirkt.
nein ich schmetter sie nicht ab, ich verteidige lediglich meine ansicht.
Die Möglichkeiten der IDE zu benutzen ist meiner Ansicht nach ganz klar weniger aufwendig, schon allein deswegen, weil man sich den Kopf freihalten kann, von irgendwelchen Konventionen.
da kann ich dich beruhigen, nach ner zeit hat man es drauf, es ist wie tippen auf der tastatur, darüber muss man nicht mehr nachdenken, man macht es aus gewohntheit dann so.
Klarerweise ist das allein kein Argument für IDEs oder nur ein sehr schwaches, andererseits bleibt eben noch die offene Frage im Raum, welchen Vorteil Präfixe im Vergleich zu den Möglichkeiten einer IDE existieren?
wieso sollten sich IDE und prefixe unbedingt ausschliessen? nur weil man eine IDE hat, muss man doch nicht auf die vorteile einer styleguide verzichten. ich kann jetzt natürlich das argument bringen, dass nicht jede IDE gleich arbeitet und gerade diff-tools oft auf das highlighting von unterschieden spezialisiert sind, nicht auf syntax;) und sourcebrowsen in sourcedatenbanken ganz andere highlights setzt.
-
kingruedi schrieb:
Ich meine nur, das eine Namensrichtlinie nicht viel bringt. Natürlich ist es wichtig dass der Code lesbar und weitesgehend einheitlich ist. Aber ich halte nichts davon, dass man Namen mit Typinformationen versieht, die dann auch noch durch 1 buchstabige Abkürzungen ausgedrückt werden.
Ich sehe so ein Vorgehen eher als mangel von Codingrichtlinien. Die müssen ja nicht sehr streng sein und können zum größten Teil aus Effektiv C++ und Exceptional C++ bestehen.
wie ich schon sagte, je besser man dem menschen die daten representiert, desto besser kann er damit arbeiten. Namen die eindeutige (wichtige) eigenschaften mitteilen vermeiden falsche annahmen.
eigentlich meinte ich, ich würde kein erstes mal nachdenken
Aber wie gesagt, es bringt mir keinen Mehrwert zu wissen ob es ein Struct oder eine Klasse ist. (siehe unten)
klar, bewust nicht, aber eine annahme würdest du zwangsweise machen damit du damit arbeiten kannst denk ich mir.
Hier hilft ein vernünftiger Codingstandard. Die freigabe wird ja nicht dadurch erledigt, in dem man ein p an einen Variablennamen hängt. Hier hilft es zB in dem man Resourcenfreigabe automatisiert. Man sollte also lieber durch die Codelogik Fehler vermeiden und nicht durch Namensgebung.
aus gründen der effiziens und manchmal durch zwänge externer libs (z.b. d3d), kann man kein automatisches resourcehandlich von anfang an machen, sondern muss eine kapselung davon schreiben oder muss damit leben.
rapso schrieb:
Das ist aber ziemlich wenig und ziemlich nutzlos. Gut CImageDescriptor braucht einen Ctor, aber welche Parameter hat er? Welche Daten enthält SImageDescriptor, wie muss ich es also initialisieren? etc. Also muss ich immer noch nachschlagen, wenn ich ImageDescriptor benutzen will. Die gegebenen Informationen bringen mir nichts.
wenn du die arbeitsweise weißt, mußt du nicht mehr nachsehen, trotzdem mußt du beim arbeiten eventuell differenzieren zwischen CImageDescriptor und IImagedescriptor.
-
Blue-Tiger schrieb:
Wo wir beim Verarbeiten sind: was machst du wenn erkennst, dass die Ergebnisse deines Programmes nicht genau genug sind, und du deine Variablen alle von float auf double umstellen musst? Durch den ganzen Quelltext gehen und alle "f"-Prefixe durch "d"-Prefixe ersetzen? Oder wenn du statt Comboboxen doch lieber ein List-Element einsetzen willst? alle cmb durch lst ersetzen?
das macht man zum teil mit http://en.wikipedia.org/wiki/Refactoring und um die umschreibung der parameter und aufrufe beim umstellen auf andere typen kommt er nicht herum. du mußt ja auch durch den source (oder zumindestens die consts gehen) und die multiplikationen mit anderen floats dann umcasten oder gleich auf double umstellen.
-
rapso schrieb:
und wenn du eine neue member einbaust die du nutzen möchtest, prüfst du dann in der implementierungsdatei ob der variablenname schon in funktionen benutzt wurde und änderst den dort oder wie ist der workflow?
Nein, aber da ich selten globale Variablen hab, krieg ich da kaum Konflikte.
Lokale Variablen in Funktionen heissen bei mir oft gleich, die verlieren ja ihre gültigkeit beim Verassen des Blocks.void move( int x_, int y_, object& elem ) elem.x = x_ elem.y = y_ } void check( int x_, int y_ object& elem ) if( x_ == elem.x ) && ( y_ == elem.y ) { foo(); }
Gut ehrlich gesagt sind meine Projekte noch nicht so gross, so dass ich einigermassen im Kopf hab, wie was heisst, und sonst weiss ich wo ich nachschauen muss.
Ausserdem hilft mir die alte Laboranten Regel: Alles eindeutig beschriften!
-
Also davon, die Datentypen als Kürzel hinzuzufügen, halte ich gar nichts. Wer den Code liest, sieht auch die Typdefinitionen - und dort steht wirklich drin, ob das nun eine int- oder long-Variable ist. Da ändere ich lieber einmal die Definition "int val;" nach "long val;", wenn mir die Genauigkeit nicht reicht, als jedes Vorkommen von "ival" in "lval" umzuwandeln (und am Ende erwische ich dann noch ein Vorkommen, das zu einer ganz anderen Variablen gehört).
Was Sinn macht, sind logische Kennzeichnungen für die Variablen (z.B. ob dieser char* auf einen 0-terminierten String zeigt oder auf einen Bereich, der die Länge explizit mitführt) - sowas kann man nicht aus den reinen Deklarationen entnehmen, sondern benötigt Zusatzinformationen.
-
CStoll schrieb:
Was Sinn macht, sind logische Kennzeichnungen für die Variablen (z.B. ob dieser char* auf einen 0-terminierten String zeigt oder auf einen Bereich, der die Länge explizit mitführt) - sowas kann man nicht aus den reinen Deklarationen entnehmen, sondern benötigt Zusatzinformationen.
Hier lässt sich natürlich auch darüber streiten, ob man dafür dann nicht einfach nen eigenen Typ einführt, oder ein aussagekräftigeres typedef nimmt.
-
CStoll schrieb:
Also davon, die Datentypen als Kürzel hinzuzufügen, halte ich gar nichts. Wer den Code liest, sieht auch die Typdefinitionen - und dort steht wirklich drin, ob das nun eine int- oder long-Variable ist. Da ändere ich lieber einmal die Definition "int val;" nach "long val;", wenn mir die Genauigkeit nicht reicht, als jedes Vorkommen von "ival" in "lval" umzuwandeln (und am Ende erwische ich dann noch ein Vorkommen, das zu einer ganz anderen Variablen gehört).
für fälle bei denen man sich über den datentypen nicht sicher ist, sollte man einen typen per typedef deklarieren. es wäre sonst viel zu fehleranfällig nachträglich im source den typen zu ändern, da müßte man durch alle stellen an denen damit gearbeitet wird um dort sicherzustellen, dass auch dort der richtige typ angenommen wird. ein typedef ist da wesentlich sicherer, weil darauf der rest vom source auch aufbauen kann.
CStoll schrieb:
Was Sinn macht, sind logische Kennzeichnungen für die Variablen (z.B. ob dieser char* auf einen 0-terminierten String zeigt oder auf einen Bereich, der die Länge explizit mitführt) - sowas kann man nicht aus den reinen Deklarationen entnehmen, sondern benötigt Zusatzinformationen.
auch dafür sollte man typenbezeichnungen nehmen, denn wenn deine var in anderen sourcen verwendet wird (mit accessor-function ausgelesen), ist garnicht mehr so sicher, dass dort die information ankommt die du im namen hattest. bei datentypen/typedefs sollte das weiterhin klar bleiben (sofern nicht jemand auf die "lustige" idee kommt es umzucasten, aber da kann man im debug templates/klassen drumrumbauen die kein casten erlauben).
-
1310-Logik schrieb:
Nein, aber da ich selten globale Variablen hab, krieg ich da kaum Konflikte.
Lokale Variablen in Funktionen heissen bei mir oft gleich, die verlieren ja ihre gültigkeit beim Verassen des Blocks.void move( int x_, int y_, object& elem ) elem.x = x_ elem.y = y_ } void check( int x_, int y_ object& elem ) if( x_ == elem.x ) && ( y_ == elem.y ) { foo(); }
Gut ehrlich gesagt sind meine Projekte noch nicht so gross, so dass ich einigermassen im Kopf hab, wie was heisst, und sonst weiss ich wo ich nachschauen muss.
Ausserdem hilft mir die alte Laboranten Regel: Alles eindeutig beschriften!ich sprech auch eher von membern in klassen, globale variablen nutzt man in c++ eigentlich garnicht mehr (ich hab jedenfalls keinen fall an dem ich das noch nutze), kann man zwar machen, aber kann man in klassen kapseln.
in deinem source wären die _ eigentlich auch garnicht mehr nötig, weil du damit ja keine vars im scope "überschreibst" denk ich mir.
-
rapso schrieb:
ich sprech auch eher von membern in klassen, globale variablen nutzt man in c++ eigentlich garnicht mehr (ich hab jedenfalls keinen fall an dem ich das noch nutze), kann man zwar machen, aber kann man in klassen kapseln.
in deinem source wären die _ eigentlich auch garnicht mehr nötig, weil du damit ja keine vars im scope "überschreibst" denk ich mir.ach so, stimmt. ja bei members mach ichs genau so
void rabbit::move( int x_, int y_ ) x = x_; // x und y sind Membervariable y = y_; }
hier brauch ich den _
na ja, den _ hab ich mir generell angewöhnt für temporäre variablen, (zB auch in if abfragen) , anstatt x_temp zu schreiben.
das mit den globals ist schon klar, hab aber im moment noch einen mischcode wegen der SDL, die ich mal grob ausm tutorial übernommmen hab. werd die dann auch noch kapseln, aber erstmal muss ich wissen, wie der hase läuft
-
1310-Logik schrieb:
hier brauch ich den _
na ja, den _ hab ich mir generell angewöhnt für temporäre variablen, (zB auch in if abfragen) , anstatt x_temp zu schreiben.
das mit den globals ist schon klar, hab aber im moment noch einen mischcode wegen der SDL, die ich mal grob ausm tutorial übernommmen hab. werd die dann auch noch kapseln, aber erstmal muss ich wissen, wie der hase läuftob du nun die localen grundsätzlich makierst, oder die member, am ende hast du die selbe differenzierung, die ich als nützlich ansprach
-
rapso schrieb:
CStoll schrieb:
Also davon, die Datentypen als Kürzel hinzuzufügen, halte ich gar nichts. Wer den Code liest, sieht auch die Typdefinitionen - und dort steht wirklich drin, ob das nun eine int- oder long-Variable ist. Da ändere ich lieber einmal die Definition "int val;" nach "long val;", wenn mir die Genauigkeit nicht reicht, als jedes Vorkommen von "ival" in "lval" umzuwandeln (und am Ende erwische ich dann noch ein Vorkommen, das zu einer ganz anderen Variablen gehört).
für fälle bei denen man sich über den datentypen nicht sicher ist, sollte man einen typen per typedef deklarieren. es wäre sonst viel zu fehleranfällig nachträglich im source den typen zu ändern, da müßte man durch alle stellen an denen damit gearbeitet wird um dort sicherzustellen, dass auch dort der richtige typ angenommen wird. ein typedef ist da wesentlich sicherer, weil darauf der rest vom source auch aufbauen kann.
Ich bin mir über den Typ ja sicher - ich brauche einen Ganzzahltyp. Und eine Unterscheidung zwischen "Ganzzahl-Variable" und "Gleitkomma-Variable" könnte ich noch verstehen, aber wenn man gesonderte Kürzel für int/long oder float/double einführt, ist das eher fehleranfällig als hilfreich
CStoll schrieb:
Was Sinn macht, sind logische Kennzeichnungen für die Variablen (z.B. ob dieser char* auf einen 0-terminierten String zeigt oder auf einen Bereich, der die Länge explizit mitführt) - sowas kann man nicht aus den reinen Deklarationen entnehmen, sondern benötigt Zusatzinformationen.
auch dafür sollte man typenbezeichnungen nehmen, denn wenn deine var in anderen sourcen verwendet wird (mit accessor-function ausgelesen), ist garnicht mehr so sicher, dass dort die information ankommt die du im namen hattest. bei datentypen/typedefs sollte das weiterhin klar bleiben (sofern nicht jemand auf die "lustige" idee kommt es umzucasten, aber da kann man im debug templates/klassen drumrumbauen die kein casten erlauben).
Ist dir schonmal aufgefallen, wie egal dem Compiler deine Namen sind? Oder daß typedef's in C++ nur eine besser klingende Alias-Bezeichnung definieren? Von daher sind solche Namenskonventionen nur für Menschen interessant, die meine Quelltexte lesen wollen. Und um alles eine Wrapperklasse drumherumzuschrauben, halte ich für Overkill (zumindest solange diese Klasse nicht mehr macht als meine internen Daten zwischenzulagern*).
*Eine String-Klasse mit eigenen Verarbeitungsmethode ist durchaus sinnvoll. Eine String-Klasse, die nur einen char* verpackt und zur Unterscheidung zwischen C-String und Pascal-String eingeführt wurde, ist nur unnötiger Aufwand.
-
rapso schrieb:
1310-Logik schrieb:
hier brauch ich den _
na ja, den _ hab ich mir generell angewöhnt für temporäre variablen, (zB auch in if abfragen) , anstatt x_temp zu schreiben.
das mit den globals ist schon klar, hab aber im moment noch einen mischcode wegen der SDL, die ich mal grob ausm tutorial übernommmen hab. werd die dann auch noch kapseln, aber erstmal muss ich wissen, wie der hase läuftob du nun die localen grundsätzlich makierst, oder die member, am ende hast du die selbe differenzierung, die ich als nützlich ansprach
Genau, nur das ich bei Zugriffen wie rabbit.x nicht mehr tippe als nötig,
während rabbit.m_uix 4 zeichen mehr sind :p
-
1310-Logik schrieb:
rapso schrieb:
1310-Logik schrieb:
hier brauch ich den _
na ja, den _ hab ich mir generell angewöhnt für temporäre variablen, (zB auch in if abfragen) , anstatt x_temp zu schreiben.
das mit den globals ist schon klar, hab aber im moment noch einen mischcode wegen der SDL, die ich mal grob ausm tutorial übernommmen hab. werd die dann auch noch kapseln, aber erstmal muss ich wissen, wie der hase läuftob du nun die localen grundsätzlich makierst, oder die member, am ende hast du die selbe differenzierung, die ich als nützlich ansprach
Genau, nur das ich bei Zugriffen wie rabbit.x nicht mehr tippe als nötig,
während rabbit.m_uix 4 zeichen mehr sind :pbei:
m_Size = Size;
tippst du
Size = Size_;
ist das der große gewinn den du hast? *hehe*ich muss m[Shift]S[Tab] = S[Tab] tippen was sollte daran so aufwendig sein?
und wie ich schon sagte, ums tippen geht es nicht, das geht parallel zum denken und bedarf 0 aufwand meinerseits
-
CStoll schrieb:
...Da ändere ich lieber einmal die Definition "int val;" nach "long val;"...
Ich bin mir über den Typ ja sicher
no offense, aber ich kann dir da nicht ganz folgen... wieso änderst du int zu long wenn du dir über den typen sicher warst, bzw widerspricht sich das nicht?
-
Als ich das Programm geschrieben habe, war ich mir noch sicher, daß int reichen sollte
(und auch jetzt reicht ein kurzer Blick, um den korrekten Typ festzustellen). Und da ist es mir lieber, überhaupt keine Typkürzel im Namen zu haben als falsche.
-
rapso schrieb:
und wie ich schon sagte, ums tippen geht es nicht, das geht parallel zum denken und bedarf 0 aufwand meinerseits
Nein, es geht um lesbarkeit. Der grosse Gewinn ist, dass ich Size im ersten überflug besser lesen kann, als m_uiSize.
-
1310-Logik schrieb:
rapso schrieb:
und wie ich schon sagte, ums tippen geht es nicht, das geht parallel zum denken und bedarf 0 aufwand meinerseits
Nein, es geht um lesbarkeit. Der grosse Gewinn ist, dass ich Size im ersten überflug besser lesen kann, als m_uiSize.
um die gegenbehauptung zu stellen: "man" kann besser m_Size lesen.
am ende kommt es nur drauf an was "man" mehr gewohnt ist.