Was ist toll an size_t?



  • EnERgYzEr schrieb:

    Wo ist der Nachteil von:

    int iObjectID
    

    ??

    Der Nachteil ist, dass es nicht wartbar ist. Wenn du den Typ änderst, dann mußt du durch die Änderung auch überall den Namen ändern, was nicht praktikabel ist. Das hat übrigens dazu geführt, dass in einigen Bibliotheken die Namensgebung nicht mehr mit den Typen konsistent ist. Ich glaube, ich hatte da mal ein Beispiel aus den MFC gesehen, wo das so war.



  • // Edit2: auch das m_ macht IMHO Sinn

    Begründung? Dass ich hässliche Unterstriche schreiben muss, kann der Vorteil nicht sein, also muss ich fragen, warum du das gut findest.



  • Hier mal der Text aus "How to write unmaintainable code" zu der ungarischen Notation:

    Hungarian Notation is the tactical nuclear weapon of source code obfuscation techniques; use it! Due to the sheer volume of source code contaminated by this idiom nothing can kill a maintenance engineer faster than a well planned Hungarian Notation attack. The following tips will help you corrupt the original intent of Hungarian Notation:

    * Insist on using "c" for const in C++ and other languages that directly enforce the const-ness of a variable.
    * Seek out and use Hungarian warts that have meaning in languages other than your current language. For example insist on the PowerBuilder "l_" and "a_ " {local and argument} scoping prefixes and always use the VB-esque style of having a Hungarian wart for every control type when coding to C++. Try to stay ignorant of the fact that megs of plainly visible MFC source code does not use Hungarian warts for control types.
    * Always violate the Hungarian principle that the most commonly used variables should carry the least extra information around with them. Achieve this end through the techniques outlined above and by insisting that each class type have a custom wart prefix. Never allow anyone to remind you that no wart tells you that something is a class. The importance of this rule cannot be overstated: if you fail to adhere to its principles the source code may become flooded with shorter variable names that have a higher vowel/consonant ratio. In the worst case scenario this can lead to a full collapse of obfuscation and the spontaneous reappearance of English Notation in code!
    * Flagrantly violate the Hungarian-esque concept that function parameters and other high visibility symbols must be given meaningful names, but that Hungarian type warts all by themselves make excellent temporary variable names.
    * Insist on carrying outright orthogonal information in your Hungarian warts. Consider this real world example: "a_crszkvc30LastNameCol". It took a team of maintenance engineers nearly 3 days to figure out that this whopper variable name described a const, reference, function argument that was holding information from a database column of type Varchar[30] named "LastName" which was part of the table's primary key. When properly combined with the principle that "all variables should be public" this technique has the power to render thousands of lines of source code obsolete instantly!
    * Use to your advantage the principle that the human brain can only hold 7 pieces of information concurrently. For example code written to the above standard has the following properties:
    o a single assignment statement carries 14 pieces of type and name information.
    o a single function call that passes three parameters and assigns a result carries 29 pieces of type and name information.
    o Seek to improve this excellent, but far too concise, standard. Impress management and coworkers by recommending a 5 letter day of the week prefix to help isolate code written on 'Monam' and 'FriPM'.
    o It is easy to overwhelm the short term memory with even a moderately complex nesting structure, especially when the maintenance programmer can't see the start and end of each block on screen simultaneously.

    und

    One followon trick in the Hungarian notation is "change the type of a variable but leave the variable name unchanged". This is almost invariably done in windows apps with the migration from Win16 :- WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam) to Win32 WndProc(HWND hW, UINT wMsg, WPARAM wParam, LPARAM lParam) where the w values hint that they are words, but they really refer to longs. The real value of this approach comes clear with the Win64 migration, when the parameters will be 64 bits wide, but the old "w" and "l" prefixes will remain forever.



  • Optimizer schrieb:

    Mir ist es lieber, wenn ich eine Variable sehe und anhand des Namens erkenne, "aha die Variable ist dafür da, das heisst sie enthält den Wert, den ich für des und des brauche."

    das eine schliesst das andere nicht aus. man schreibt erst den ungarische-notations-schnickschnack und dann die bedeutung in den variablennamen.

    Gregor schrieb:

    Der Nachteil ist, dass es nicht wartbar ist. Wenn du den Typ änderst, dann mußt du durch die Änderung auch überall den Namen ändern, was nicht praktikabel ist.

    das ist unbestreitbar der grösste nachteil



  • lol, ist das der selbe Typ, der empfiehlt, in Java die Arrays möglichst undurchsichtig zu deklarieren??

    int[] foo[][], bar, foo2[]; double[] d[];
    

    Der ist locker drauf. 😃



  • das eine schliesst das andere nicht aus. man schreibt erst den ungarische-notations-schnickschnack und dann die bedeutung in den variablennamen.

    Gut, aber ich hab immer noch nicht begriffen (und du wirst es auch nicht schaffen, mich zu überzeugen :p ), warum das überhaupt relevant sein soll, von welchem Typ die Variable ist. Ich schau mir ein Stück Code an und versuche es, zu verstehen.
    Da ist mir des sooooo wurscht, dass das ein std::list<foo*>::const_iterator ist. Da interessiert mich das wesentlich mehr, dass dieser Iterator dazu gedacht istn über meine liste zu iterieren und alle meine foos, die weniger als 3 bars haben (um mal irgendwas schwachsinniges zu erfinden), löscht.



  • Optimizer schrieb:

    // Edit2: auch das m_ macht IMHO Sinn

    Begründung? Dass ich hässliche Unterstriche schreiben muss, kann der Vorteil nicht sein, also muss ich fragen, warum du das gut findest.

    Dazu fällt mir nur folgendes ein:

    a naming convention from the world of C++ is the use of "m_" in front of members. This is supposed to help you tell them apart from methods, so long as you forget that "method" also starts with the letter "m".

    🙂



  • Optimizer schrieb:

    Klasseninstanzen sollen einen Namen haben, der ihre Bedeutung im Programm erklärt und nicht erklärt, von was für einem Typ sie sind.

    Vorallem weil der Typ ja egal ist. Es ist ja nicht die Klassenorientierte Programmierung, sondern die Objektorientierte.

    Wenn ich sage

    shape.draw();

    dann ist es doch egal, ob shape nun ein Kreis, Quadrat, Hund oder Foobar ist. Er weiss ja selber wie er sich zeichnen soll 😉

    Jetzt kommt sicher gleich: ja, aber bei primitiven Typen...

    Und dann werde ich sagen:
    Int32 i=7;
    cout<< i+3;

    es wird 10 ausgegeb, stimmts?
    Es ist doch total egal ob Int32 ein simples typedef auf int ist, oder ob Int32 eine extrem komplizierte Klasse ist, die intern zB GMP verwendet, oder so.

    Sie verhaelt sich wie ein integer - weil sie auch genau das ist. Wozu muss ich jetzt wissen, ob das eine Klasse, ein typedef oder sonstwas ist?

    Der Typ interessiert uns nicht - uns interessiert das verhalten. Also mach meinetwegen eine polnische Notation - mit sowas kann ich leben.

    Edit:

    zu dem m_*
    sowas machen nur masochisten - weil dann die IDE nicht so schoen helfen kann - weil die signifikanten stellen dann ja erst ab derm 3. buchstaben anfangen.

    Also wer Member kennzeichnen muss (zB. weil er zuviel zeit hat) - der kann ja
    foo_ oder foo_m verwenden.

    ich fuer meinen teil finde das unnoetig. in Java kommt man ja auch bequem ohne Kennzeichnung aus...



  • Optimizer schrieb:

    lol, ist das der selbe Typ, der empfiehlt, in Java die Arrays möglichst undurchsichtig zu deklarieren??

    int[] foo[][], bar, foo2[]; double[] d[];
    

    Der ist locker drauf. 😃

    Jo, der ist das! 🙂



  • Vorteile für die abgeschwächte Verwendung von Präfixen:

    (Mit abgeschwächt meine ich z.B. kein m_lpfn *g*, sondern m_, i, f, etc.)

    - Während des codens weiß ich, was für ein Typ die Variable hat und
    kann so besser programmieren. Bei vielen Variablen und längeren Funktionen
    macht das IMHO Sinn

    - Ich kann Membervariablen von Funktionsparametern unterscheiden

    - Mir gefällt ein m_sName = sName besser als this->Name = Name

    - Der Vorschlag, dass der Compiler schon merkt, wenn eine Typzuweisung falsch
    ist, sehe ich als genauso theoretisch an - Nicht jedes Projekt lässt
    sich in 10 Sekunden compilieren - In meiner Firma sitzen wir schon mal
    10 Minuten rum, weil das MS VC mal wieder nicht gerallt hat, dass nur
    eine Datei geändert wurde 😡

    - Das Mit-Der-Maus-Rüberfahren ist beim MS VC.NET buggy und fumktioniert nicht
    immer - vor allem im Debug Modus (Ironie?) - Wann kommt endlich ein Service
    Pack, um diese ganzen s****** Bugs zu entfernen 😡 😡 😡



  • Shade Of Mine schrieb:

    Der Typ interessiert uns nicht - uns interessiert das verhalten.

    Genau mein Reden.... Das Verhalten ist das eines int - also kann ich das auch
    dazu schreiben, oder? Schließlich kann nicht jeder wissen, dass
    fjdfdjkTOLLE_ZAHLffdjk ein typedef auf ein int sein soll..

    Edit: Also ich sehe zwei Möglichkeiten:

    1.) Wir erleichtern uns die Arbeit beim coden -> ungarische Notation
    2.) Wir erschweren uns die Arbeit -> gegen ungarische Notation

    Wer den Code später lesen muss, den wird es nicht stören, wenn statt
    ObjectID iObjectID da steht. Das eine Zeichen übersieht eh jeder, der es
    nicht sehen will...

    Edit2:

    zu dem m_*
    sowas machen nur masochisten - weil dann die IDE nicht so schoen helfen kann - weil die signifikanten stellen dann ja erst ab derm 3. buchstaben anfangen.

    Das sehe ich anders - Es erleichtert die Arbeit mit der IDE. Denn, wenn ich
    m_ eingebe bin ich sofort bei allen Variablen und kann diese Liste schnell
    durchsuchen, falls mir ein Name entgangen ist. Ohne m_ darf man alle Variablen
    plus Methoden durchsuchen *ggg*

    Und bevor es jetzt heißt "Eine Variable hat so zu heißen, dass man den Namen
    nicht vergisst" - Es gibt für jede Variable mehrere Bezeichnungsmöglichkeiten.



  • aber dass man gewisse aussagen über objekte/variablen/klassen etc. in die namen codiert ist doch ok oder haltet ihr das auch für schwachsinn?

    beispiel java:
    - methoden fangen klein an, zweiter teil des namens beginnt mit grossbuchstaben
    - klassen beginnen immer gross
    - namen von konstanten bestehen nur aus grossbuchstaben



  • Du weisst aber bei Objektorientierung nicht, ob das Shape (schönes Beispiel, Shade) sich jetzt wie ein Kreis oder ein Stern verhält. Das ist auch egal. Das interressiert doch nicht. Der macht schon alles richtig.
    Was dich eher was angehen sollte, ist, ob es jetzt das Shape ist, was den oberen Bereich des Fensters schmückt, oder des Shape, was für dies und jenes zuständig ist.

    Gerade bei Polymorphie beißt du eh ins Gras. Du kannst das Teil gar nicht g_myRectangle->draw() nennen, weil es vielleicht nur vom Typ Shape ist und du den konkreten Typen erst zur Laufzeit kennst.
    Willst du es einfach g_shape nennen? Was nützt dir das? Hast du mal wirklich darüber nachgedacht, was dir das bringt?

    Mir gefällt ein m_sName = sName besser als this->Name = Name

    Mir gefällt eigentlich am besten die Initialisierliste:

    Person:Person(const string& name, int age)  :
        name(name), age(age)        {}
    


  • net schrieb:

    aber dass man gewisse aussagen über objekte/variablen/klassen etc. in die namen codiert ist doch ok oder haltet ihr das auch für schwachsinn?

    beispiel java:
    - methoden fangen klein an, zweiter teil des namens beginnt mit grossbuchstaben
    - klassen beginnen immer gross
    - namen von konstanten bestehen nur aus grossbuchstaben

    Jo, das ist ja auch sinnvoll. Sonst weiss ich ja nicht, ob Math.sqrt() jetzt eine statische Methode ist, oder ich eine Instanz mit dem Namen Math hab und die Methode nicht statisch ist. Hat aber auch nichts mit ungarischer Notation zu tun.



  • One followon trick in the Hungarian notation is "change the type of a variable but leave the variable name unchanged". This is almost invariably done in windows apps with the migration from Win16 :- WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam) to Win32 WndProc(HWND hW, UINT wMsg, WPARAM wParam, LPARAM lParam) where the w values hint that they are words, but they really refer to longs. The real value of this approach comes clear with the Win64 migration, when the parameters will be 64 bits wide, but the old "w" and "l" prefixes will remain forever.

    Wenn ich einen Typ ändere, darf ich vermutlich eh einiges ändern. Dann kann
    ich einfach den Präfix ändern und dann wird mich der Compiler schon darauf
    hinweisen, wo die Variable noch ist, woraufhin ich mir diese Stellen noch
    einmal genau ansehen kann.... (In diesem Fall ist die Compiler Methode mal
    gut *ggg*)



  • Optimizer schrieb:

    Mir gefällt eigentlich am besten die Initialisierliste:

    Person:Person(const string& name, int age)  :
        name(name), age(age)        {}
    

    Haha, toller Witz 😉 ... Es gibt auch ein SetName(string sName)



  • Nö, du kannst den Namen i.d.R. nicht ändern. Wenn du ne Lib ausgeliefert hast und mal schnell meinst, du kannst mal eben ein paar Namen ändern, dann würde mich vor den vielen aufgebrachten Benutzern deiner Bibliothek in Sicherheit bringen.



  • EnERgYzEr schrieb:

    - Während des codens weiß ich, was für ein Typ die Variable hat und
    kann so besser programmieren. Bei vielen Variablen und längeren Funktionen
    macht das IMHO Sinn

    Du hast aber weder viele Variable noch laengere Funktionen, wenn du schoen OO programmierst 😉

    bzw. wenn du soetwas hast, dann hast du die Variablen alle schoen lokal - du solltest also die Deklaration sehen koennen.

    - Ich kann Membervariablen von Funktionsparametern unterscheiden

    warum ist das wichtig?

    - Mir gefällt ein m_sName = sName besser als this->Name = Name

    mir gefaellt name am besten. Na und?

    - Der Vorschlag, dass der Compiler schon merkt, wenn eine Typzuweisung falsch
    ist, sehe ich als genauso theoretisch an - Nicht jedes Projekt lässt
    sich in 10 Sekunden compilieren - In meiner Firma sitzen wir schon mal
    10 Minuten rum, weil das MS VC mal wieder nicht gerallt hat, dass nur
    eine Datei geändert wurde 😡

    Schonmal was von pimpl gehoert?
    Naja, trotzdem. Da helfen die Praefixe auch nix - denn du hast ja nicht nur Primitive Typen - und du wirst ja nicht allen ernstes fuer jeden Typen ein Praefix erfinden, oder? Da du das nicht tun wirst, beschraenkst du dich mit den Praefixen auf die paar Builtins? Und das lohnt sich? Was machst du, wenn du statt einem int mal ein Int128 hast? Das ist momentan noch eine Klasse, aber auf einer anderen Plattform ist das aufeinmal nur ein typedef. Sehr verwirrend... zumindest fuer mich. Ich wuerde den Code dann nicht so klar finden.

    - Das Mit-Der-Maus-Rüberfahren ist beim MS VC.NET buggy und fumktioniert nicht
    immer - vor allem im Debug Modus (Ironie?) - Wann kommt endlich ein Service
    Pack, um diese ganzen s****** Bugs zu entfernen 😡 😡 😡

    Na, das sind ja mal Probleme (und vorallem ein super Grund)

    Mich hat der Typ einer Variable bisher nur dann interessiert, wenn der Compiler einen Fehler gemeldet hat (und dann war es meistens ein const Problem).

    Deine Argumente sind loechrig.

    Erklaer lieber mal _warum_ du den Typen wissen musst. zB wie machst du das bei Templates??

    Genau mein Reden.... Das Verhalten ist das eines int - also kann ich das auch
    dazu schreiben, oder? Schließlich kann nicht jeder wissen, dass
    fjdfdjkTOLLE_ZAHLffdjk ein typedef auf ein int sein soll..

    Wieso interessiert dich, dass der Typ "fjdfdjkTOLLE_ZAHLffdjk" ist? Vielleicht ist es ja kein typedef auf int, sondern eine hoch komplexe Klasse? Wuerdest du dann immer noch i als Praefix nehmen?

    Wenn i einfach nur Zahl bedeutet, dann ist das Problem doch: wenn du iNumber sagst, dann bringt das i nicht wirklich etwas. Und ein iName wird es nicht geben. Somit sagt iNumber kein bisschen mehr als number.
    Und zB s als string-Praefix. Was fuer ein string ist es denn? CString? std::string? char*? wchar_t*? oder vielleicht flex_string? Und wenn flex_string - mit welchen Policies?

    Der Sinn von OOP ist ja, dass der Typ uninteressant ist. Das Verhalten zaehlt. Und du kannst das genaue Verhalten nicht mit ein paar Buchstaben sinnvoll beschreiben.

    zB statt Zeiger hast du oft smart pointer - wie macht man da Praefixe? Prinzipiell sind es Zeiger (lassen sich ja auch genauso verwenden) - aber ein p als Praefix ist dennoch nicht richtig (weil es ja eben _doch_ unterschiede gibt - nur sind diese Unterschiede in 99% der Faelle uninteressant).

    Du bindest mit einem Praefix eine Variable an einen Typen - das geht aber nicht. Denn du koenntest ja uU mal polymorphe Objekte (ein super Beispiel, warum der Typ nicht wichtig) - wie willst du mit denen umgehen?

    Ungarische Notation passt einfach nicht in eine OO Sprache.



  • EnERgYzEr schrieb:

    Optimizer schrieb:

    Mir gefällt eigentlich am besten die Initialisierliste:

    Person:Person(const string& name, int age)  :
        name(name), age(age)        {}
    

    Haha, toller Witz 😉 ... Es gibt auch ein SetName(string sName)

    Echt? Bei mir nicht, weil eine Person in der Regel ihren Namen für das ganze Leben behält.



  • Optimizer schrieb:

    Jo, das ist ja auch sinnvoll. Sonst weiss ich ja nicht, ob Math.sqrt() jetzt eine statische Methode ist, oder ich eine Instanz mit dem Namen Math hab und die Methode nicht statisch ist. Hat aber auch nichts mit ungarischer Notation zu tun.

    hat aber die gleiche wirkung. man steckt (teilweise) typinformationen o.ä. in die namen und wenn sich am typ, spezifizierer oder so irgendwas ändert sind alle namen für die katz.


Anmelden zum Antworten