Sauberes Programmieren // Varibeln mit Prefix



  • Original erstellt von kartoffelsack:
    Und auf irgendeiner Ebene hast Du keine Objekte mehr sondern Variablen von eingebauten Typen.

    Das scheint der springende Punkt zu sein. Ich denke nicht, dass die künstlichen Unterschiede zwischen eingebauten und selbstgebautren Typen so groß ist, dass man unterscheiden muss. Nehmen wir doch mal ne Klasse BigInteger.

    Vielleicht hat er gedacht, ah, ich hab doch da ne Varible, wie hieß die nochmal? Running oder

    Oder running? Oder run? Oder Run? Und schlägst nach.

    Und wenn er den Müll trotzdem baut, is die Chance recht gut, dass er beim späteren Überfliegen stutzig wird, wenn er --bRunning sieht.

    Kommt halt auch den bool an. Es gibt noch genug Leute, die irgendwo ein '#define BOOL int' haben :(. Wie geht man bei so etwas eigentlich um? Jedes Typedef bekommt sein eigenes Präfix? Oder sind typedefs keine PODs mehr?

    ich bin nicht der einzige, der hin und wieder ne kleine schnelle Änderung machen will, die sich dann als doch nicht so klein herausstellt

    Eben. Darum mehrkt man immer recht schnell, das es sinnvoll ist, den Quelltext durchzulesen ...

    Das Kopierverhalten einer Instanz, eines Zeigers, und verschiedener Smart-Pointer ist vollkommen verschieden.

    Natürlich. Die Kopiersemantik eines Zeigers ist aber doch definiert, die eines Smartzeigers musst Du selbst definieren.

    Sie ist, je nachdem, was für eine Template-Spezialisierung mein Iterator ist, locker mal ein paar Zeilen lang mit den haut mir hunder verschachtelte '<'s um die Ohren.

    Woher soll der Compiler wissen, dass Du die kurze Version bevorzugst?

    [Es ist nicht mal so schwer sich aus seinen typedefs maschinell ein sed-Programm (oder so) zu schnitzten, dass die Ausgabe nachbearbeitet.]

    > a) es dem Gedanken der Objektorientierung zuwieder läuft

    Wurde vielleicht gesagt. Aber nicht begründet. Zumindest nicht so, dass ich es mit meinem persönlichen Verständnis von Objektorientierung verstehe.

    Das ist schade. Also nochmal:

    Polymorphie: Ich deklariere einen Zeiger auf eine Basisklasse und lasse ihn auf verschiedene abgeleitete Klassen zeigen? Welches Präfix? Was ist, wenn ich auf ein Array zeige? Dann wenden wir eben keine Präfixe an! Eben :).

    Was ich nicht sehe, da bei POD-Typen diese Abstraktion nicht machbar ist

    Auch PODs abstrahieren. ZB dieser wunderschöne POD aus netdb.h.

    struct  hostent {
                 char    *h_name;        /* official name of host */
                 char    **h_aliases;    /* alias list */
                 int     h_addrtype;     /* host address type */
                 int     h_length;       /* length of address */
                 char    **h_addr_list;  /* list of addresses from name server */
         };
    

    Sogar eingebaute Typen abstrahieren. Schlimmstenfalls die viel bemühten Elektronen aus der Siliziumschicht.

    und bei den paar Objekten, bei denen ich ein Präfix verwende der Typ wichtig ist (eine map ist etwas konzeptuell anderes als ein Vector)

    Eine map ist auch konzeptionell etwas anderes als ein CORBA-Interface. Und darum soll ich sie mit Präfixen versehen?

    c) keine Zusatzinformationen vermittelt werden

    Doch, der Typ

    ... ist keine Zusatzinformation, sondern eine Information, die ich nachschlagen kann.

    Wenn ich ein iRunning hab, und mit nem Kollegen spreche, dann sag ich trotzdem: "Das Proggi kackt ab, wenn Running kleiner als 10 wird"

    Und der Kollege antwortet 'i, o, u, ö, ä, p, r oder sder-Running'? :).

    e) es Mehraufwand für Leser und Programmier ist

    Zu vernachlässigen (s. punkt h). Sorry, ich tippe recht schnell.

    Ich auch. Aber ich finde es gut, wenn im Quelltext das drinnsteht, was mir unbekannt ist, und woüber ich denken soll. Das ist genau so unnütz wie wenn der Autor mir seine Sokengröße oder sein Geburtstag im Quelltext vermittelt. Das interessiert mich nur in begründeten Ausnahmefällen.

    f) zT falsche 'Informationen' geliefert werden

    Wann, wieso?

    Wenn jemand (ein Verrücker :)) mal nur den Typ und den Variablen nicht ändert.

    g) es zum Schlampen anregt

    ????????????????????????????

    Wie war das mit den multiplen Satzzeichen ... 🙂

    Jemand, der keine kurzen Funktionen schreiben kann hat noch ganz andere Lücken, oder: Wieso sollte ich kurze Funktionen schreiben, wenn ich doch alle Informationen aus einer Zeile gewinnen kann?

    Es ist definitv ein größerer Mehraufwand, mir nen Fehler vom Compiler melden zu lassen, als den Fehler aufgrund der Notation gleich garnicht zu machen.

    Sicher. Es ist toll keine Fehler zu machen.

    Der Meinung bin ich z.B. nicht. Nur tu ich persönlich mich schwerer, da ich zuviel in den deklarationen nachlesen muss, was mich stört.

    Wenn Du meinst, dass es für dich eine Arbeitsverminderung ist, tue das. Aber für mich bedeutet es Mehraufwand.

    Ich hab ein paar Beispiele gebracht, wo er imho wichtig ist (ich wiederhol mich auch gern: verschiedene Smart-Pointer-Implementationen).

    Vielleicht könnte man sogar sagen, dass es zu wichtig ist, um in einer Notation aufzutauchen ("Namen sind Schall und Rauch" -- volkard).

    ich kenne nicht viele Projekte, wo die Doku immer so exakt auf dem neuesten Stand - und noch dazu fehlerfrei - ist, dass das klappt.

    Hauptsache mit der Variablennotation klappt's? 🙂

    Ich liebe übrigens endlose Grundsatzdiskussionen 😉

    Ob Du es glaubst oder nicht: Ich auch :).



  • @kartoffelsack
    f)

    Wann, wieso?

    class base { /*...*/ }; class derive : public base { /*...*/ };
    //...
    base *pbVar; //pb == pointer auf base
    derive x;
    pbVar=&x; //ui
    

    g)

    Es ist definitv ein größerer Mehraufwand, mir nen Fehler vom Compiler melden zu lassen, als den Fehler aufgrund der Notation gleich garnicht zu machen.

    Wobei du auch den Aufwand der Notation beachten solltest.

    NUR: in dieser Hausnummer hast Du eine Membervariable und das ist ein int, ein string oder k.a. was.

    ja, ka. was, dass ist genau der Punkt, wenn ich mit einer Hausnummer arbeite, dann ist es mir egal, wie die Klasse intern aufgebaut ist, dann interessiert mich nur die Schnitstelle und da benutzt man ja wohl selbst als UN Freak (merkwürdiger Weise, wie Shade und ich bereits angedeutet haben) keine UNotation und erreicht also keinen Vorteil und falls ich mich dann doch mit dem Innenleben der Klasse befassen muss, dann kann ich mir auch nochmal die deklaration ansehen bzw. sehe eh durch den Quellcode was das für ein Typ ist (machmal arbeite ich auch mit 2 Editor Fenstern, einmal schau ich mir die deklaration und dann die Implementierung an, dadurch hab ich sicher weniger Zeitverlust, als durch das merken und benutzen eine Notation, die auf geheimnisvollen Abkürzungen basiert).

    Würd er Prefixes verwenden, hätt er iRunning geschrieben und der Compiler hätts ihm um die Ohren gehauen.

    Wie gesagt, der Compiler weiss uach ohne Prefix, welchen Typ die Variable hat

    Nein, hindern tut sie mich nicht, aber ansonsten zwingt mich der Compiler dazu.

    Also dient UN dir dazu, dass du Quellcode liest, in dem du dir mehr Arbeit machst

    e)/h)

    Zu vernachlässigen

    du sagst selber, dass du gezwungen bist den gewsammten Quellcode dadurch zu lesen, bei marginalen Änderungen und deswegen ist der Aufwand wohl doch größer. Nebenbei bemerkt hat es wohl nichts damit zu tun, wie schnell du etwas tippen und wie schnell du etwas lesen kannst

    Klar. Aber die halbe Stunde umbenennen spar ich mir leicht wieder rein, wenn ich bei ner Variable anhand ihres Vorkommens 5 Zeilen weiter oben im gleichen Fenster sehe, welchen Typ denn das Ding hat, anstatt wenn ich in den Header zur Klassendeklaration gehe nachgucke (zwischen den vielen Beschreibeungen 😉 ), zurückgehe, das Telefon klingelt und ich danach nochmal nachgucken muss.

    Also ich kann wie gesagt auch 2 Editor Fenster nehmen, in einem ist die Deklaration im anderen der Code (der Emacs bietet zB. ein Feature zu aufteilen des Bildschirms, bei anderen IDEs/Editoren wird es sowas wohl auch geben)

    Das Dilemma versteh ich, akzeptiere ich aber. Aus mehreren Gründen: - Funktions-Deklarationen (also Schnittstellen) ändere ich seltener, und benutz ich im gesamten Projekt häufiger. Das is eher was, was in mein Langzeitgedächtnis kommt.

    Also ich komm oft mit der Argument Reihenfolge durcheinander, wobei mir da je nachdem eh keine UN hilft, wenn Argumente den gleichen Typ haben 🙂 und am Anfang des Projektes passiert es mir oft, dass ich viel umbaue (manchmal auch noch deutlich später). Also wenn du UN benutzt, damit du mehr Code liest, versteh ich nicht, wieso das für Funktionen nicht benutzt werden sollte (gerade wenn Funktionen heufiger verwendet werden, liest du doch mehr Code) und wenn du UN benutzt um leichter mit den Typen umzugehen frag ich mich, warum du bei Funktionen, die du ja wie du selber sagst heufiger benutzt dir die Arbeit nicht leichter machen willst. Das du dir vielleicht die Argumente einer Funktion gut merken kann, glaub ich dir, aber es gibt auch Funktionen die man seltener benutzt oä. ich glaub nicht, dass du 100 Funktionen auswendig kannst, ich muss regelmäßig in die Doku nochmal gucken

    @Mastha

    Also ich weiß durch die Präfixe und den Namen immer was gemeint ist.

    und was trägt der Präfix dazu bei? Also ich versuche Variablen immer so zu benennen, dass klar ist, was diese Variablen sollen.

    Ich finde es einfach nur schade, dass hier einige wenige Leute meinen ihr Style sei der einzig wahre und es gibt nix besseres.

    Nein, es geht hier nicht darum, dass mein Stiel der beste ist, sondern das UN Sinnlos ist, komm jetzt bitte nicht auf die Tour, dann brauchen wir ja gar nicht diskutieren 🙄



  • Oder running? Oder run? Oder Run? Und schlägst nach.

    Ne ich bin mir fast sicher. Ich schlage nicht nach. Und da mir der Compiler nen Fehler meldet, wenn ich mich getäuscht hab, bin ich auf der sicheren Seite.

    Kommt halt auch den bool an. Es gibt noch genug Leute, die irgendwo ein '#define BOOL int' haben . Wie geht man bei so etwas eigentlich um? Jedes Typedef bekommt sein eigenes Präfix? Oder sind typedefs keine PODs mehr?

    defines erkenn ich, weil sie GROSS geschrieben sind. Außerdem muss ich mich jetzt outen: ich mag typedefs nicht. Warum? Weil ich nicht weiß, welcher Typ dahinter steht. Ich arbeite da gerade an nem Projekt. Da muss ich mich durch 3 typedefs durchkämpfen bis ich weiß, dass die ID ein __int64 ist. Schrecklich. ID steht im Namen. Das reicht mir. Ich brauch kein typedef für ID. Ich seh das übrigens ähnlich mit size_type aus der stl (jetzt fallt Ihr über mich her): Wenn ich die Größe von nem Container speicher will, dann heißt die Variable (jetzt mal ohne Prefix): SizeOfAutos. Da interessiert es mich nicht, das der Typ size_type ist. Es interessiert mich aber hin und wieder schon, was das für ein "echter" Typ is. Z.B. wenn mich der Compiler warnt, dass ich signed und unsigned-Integers vergleiche.

    Eben. Darum mehrkt man immer recht schnell, das es sinnvoll ist, den Quelltext durchzulesen ...

    Ja aber entweder sagt mir der Compiler "hey, lies den Code durch" oder das Proggie stürzt irgenwo komisch ab.

    Die Kopiersemantik eines Zeigers ist aber doch definiert, die eines Smartzeigers musst Du selbst definieren.

    Ja und deswegen möchte ich wissen, ob das Teil ein std::auto_ptr oder ein boost::smart_pointer is. Und zwar auf den ersten Blick, da wo er verwendet wird. Damit ich gleich auf garkeine dummen Gedanken komme.

    Woher soll der Compiler wissen, dass Du die kurze Version bevorzugst?
    [Es ist nicht mal so schwer sich aus seinen typedefs maschinell ein sed-Programm (oder so) zu schnitzten, dass die Ausgabe nachbearbeitet.]

    hm ich denk es geht den meisten so. Weil mit den langen kann man eigentlich nie was anfangen. Wie geht das mit dem sed-Programm?

    Also nochmal:
    Polymorphie: Ich deklariere einen Zeiger auf eine Basisklasse und lasse ihn auf verschiedene abgeleitete Klassen zeigen? Welches Präfix? Was ist, wenn ich auf ein Array zeige? Dann wenden wir eben keine Präfixe an! Eben .

    Also nochmal: ich - und soweit ich hier gelesen habe auch alle anderen Präfix-Anhänger, verwende keine Präfixe für Klassen (bei mir von ein Paar ausnahmen abgesehen). Und wenn ich ne Klasse Fahrzeug hab und ein pFahrzeug auf ein Auto zeigen lassen will, heißt dieser Zeiger selbstverständlich pFahrzeug.

    Auch PODs abstrahieren. ZB dieser wunderschöne POD aus netdb.h.

    Ich meine mit PODs eingebaute Typen. Sorry für meine falsche Verwendung. Structs sind für mich Klassen (wie für den Compiler auch).

    Doch, der Typ

    ... ist keine Zusatzinformation, sondern eine Information, die ich nachschlagen kann.

    hm, ich will IMMER wissen, mit welchem Typ ich arbeite (und bei Templates will ich wissen, dass ich mit einem Beliebigen arbeite). Vielleicht würd ich mich dran gewöhnen, wenn ich die Info nicht immer hätte, aber in meinen Projekten hab ich die Info immer parat und das find ich gut so.

    Und der Kollege antwortet 'i, o, u, ö, ä, p, r oder sder-Running'?

    Vielleicht sagt er: das Running is doch ein bool, Du Idiot! Das hat er sich aber sicher eher gemerkt, wenn ers dauern gelesen hat im Code.

    Wenn jemand (ein Verrücker ) mal nur den Typ und den Variablen nicht ändert.

    Komisch, aber dieser Fehler ist mir wirklich noch nie passiert. Weil ich weiß ich muss es ändern sonst wird alles scheiße.

    "Namen sind Schall und Rauch"

    Gut, dann mach ich jetzt aus meinem strHausnummer ein z.

    Hauptsache mit der Variablennotation klappt's?

    Klappt bei mir ganz gut. Aber meine Doxygen doku is auch immer auf dem aktuellsten Stand. Nur nicht immer erzeugt oder neue Module werden beim Erzeugen nicht erfasst. Und je dichter was am Code steht, desto eher isses aussagekräfitg.

    b Du es glaubst oder nicht: Ich auch

    Na das kann ja heiter werden 😃 😉



  • pbVar=&x; //ui

    derived IST EIN base. Das is völlig ok. (oder überseh ich da grad ne Falle 😕 ). Nur die Namensgebung Var und x is halt scheiße.

    dass ist genau der Punkt, wenn ich mit einer Hausnummer arbeite,

    Ich hab gesagt, dass ich nich mit ner Klasse Hausnummer arbeite. Die operatoren, die mir string, unsigned oder int zur verfügung stellen (<<, = und ==) reichen mir vollkommen. Fällt mir nicht ein bei ner Adressverwaltung ne Klasse Hausnummer zu schreiben. Kritisiert mich dafür, aber nicht für das Präfix des Attributs der Klasse "Adresse"

    Wobei du auch den Aufwand der Notation beachten solltest.

    Welchen Aufwand denn? Dass der Tippaufwand nicht zählt, sind wir uns ja wohl einig. Und dass das ändern länger dauert, weil man sich den Code durchgucken MUSS seh ich als Vorteil (man überlegt sich außerdem dann vielleicht vorher schon genauer, welcher Typ sinnvoll ist).

    Also dient UN dir dazu, dass du Quellcode liest, in dem du dir mehr Arbeit machst

    Strenge Typisierung zwingt mich auch zu etwas, was mir mehr Arbeit macht. In der Hoffnung, dass es mir danach umso mehr Arbeit erspart.

    Also ich kann wie gesagt auch 2 Editor Fenster nehmen, in einem ist die Deklaration im anderen der Code (der Emacs bietet zB. ein Feature zu aufteilen des Bildschirms, bei anderen IDEs/Editoren wird es sowas wohl auch geben)

    Ich hab zwei Monitore, x Fenster offen und die IDE ordnet mir - leider - nicht automatisch .h und .cpp nebeneinander an. Außerdem will ich ja evtl nicht nur den eigenen Header sonder auch noch drei Header von Klassen, die ich grad verwende offen haben.

    Also wenn du UN benutzt, damit du mehr Code liest, versteh ich nicht, wieso das für Funktionen nicht benutzt werden sollte (gerade wenn Funktionen heufiger verwendet werden, liest du doch mehr Code) und wen...

    Hab auch schon oft drüber nachgedacht, ob ich die Typinfos auch in die Funktionen aufnehmen soll (und wenn ich ganz ehrlich bin, mach ichs auch meist ein p rein (oh, oh), wenn ich nen Pointer kriege. Also GetpFahrzeug("Mercedes") ). Warum ich mich immer dagegen entscheide? Kann ich nich so wirklich durchgängig erklären - zumindest nicht mehr als ich schon hab. Is ne Unstimmigkeit? Na und. Besser den Vorteil nur bei nem - streng abgegrenzten - Teil als garnicht.

    sondern das UN Sinnlos ist

    Vielleicht, warum es manche/viele für sinnlos halten.



  • wenn man jetzt nur UN bei Builtin Typen hat, dann rentiert sich das ganze irgendwie nicht, oder?

    Builtin Typen hab ich nur ganz unten. Der meiste Code hat mit denen relativ wenig zu tun.

    ausserdem sollen sich Klassen wie normale Typen verhalten, so hat mans mir zumindestens beigebracht. warum sollte ich nun trennen?

    mein Compiler gibt mir übrigens ne fehlermeldung aus, wenn ich --running schreibe obwohl running ein bool ist...

    was bringts mir also? wenn ich nen fehler mache sagts mir der compiler.

    warum magst du denn typedefs nicht? die sind eine sehr nützliche einrichtung.

    Ja und deswegen möchte ich wissen, ob das Teil ein std::auto_ptr oder ein boost::smart_pointer is. Und zwar auf den ersten Blick, da wo er verwendet wird. Damit ich gleich auf garkeine dummen Gedanken komme.

    also doch prefixe bei objekten??
    na dann gute nacht...



  • Original erstellt von kartoffelsack:
    ich mag typedefs nicht. Warum? Weil ich nicht weiß, welcher Typ dahinter steht.

    Das ist doch der Sinn der Sache. Du weißt, dass es sich um ähnliche Typen handelt. Näherer Informationen uninteressant. Findest Du zB auch stdint.h in C böse, weil ich mir da einen passenden 16-Bit-Integer raussuchen kann?

    Da interessiert es mich nicht, das der Typ size_type ist.

    Eben. Der Typ ist nicht interessant :).

    Es interessiert mich aber hin und wieder schon, was das für ein "echter" Typ is

    ... und wenn es zur Abwechslung mal kein 'echter Typ' ist (sondern eine Compilererweiterung).

    Ja und deswegen möchte ich wissen, ob das Teil ein std::auto_ptr oder ein boost::smart_pointer is

    Womit ich ja wissen müsste, wie diese Dinger intern aufgebaut sind. Das alles auf ein (vielleicht 3-zeichen-langen) Präfix zu reduzieren ist doch etwas waghalsig.

    Wie geht das mit dem sed- Programm?

    Einfach Spezielles suchen und ersetzten: 'basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >' durch 'string' zB. Sich die typedefs maschinell erzeugen zu lassen ist doch recht kompliziert, wenn man mit Funktionszeigern arbeiten will.

    [Soweit ich seh' lässt sich so etwas schön in den Emacs integrieren.]

    ich will IMMER wissen, mit welchem Typ ich arbeite

    Ich nicht. Mich interesieren (wie schon öfters gesagt) die abstrakten Schnittstellen ('ich kann Addieren'). Ob dabei nun intern 2 Assemblerbefehle generiert werden, die dann intern in 0.007 Mikrosekunden verwenden ist mir als Hochsprachenprogrammierer egal.

    [Synchronisation von Nemen und Code] Komisch, aber dieser Fehler ist mir wirklich noch nie passiert.

    Was an seiner Existenz nichts ändert.

    > "Namen sind Schall und Rauch"
    Gut, dann mach ich jetzt aus meinem strHausnummer ein z.

    Ändert an der Programmsemantik nichts.

    derived IST EIN base.

    'typeid (base) == typeid (derived)'?

    Gleichheit ist insgesamt etwas komisch, nicht nur, was Computer anbetrifft ('das Gleiche' vs 'das Selbe').

    Strenge Typisierung zwingt mich auch zu etwas, was mir mehr Arbeit macht.

    ZB? (Mehr Tippaufwand gilt nicht :))



  • Original erstellt von Daniel E.:
    ZB? (Mehr Tippaufwand gilt nicht :))

    Basis klassen getue und new einsatzt (smart pointer) könnte man sich sparen

    aber auf der anderen seite spart typenstrengeheit arbeit(debug) und laufzeit(IMHO)



  • Eine Basisklasse hat mit Typenprüfung ähnlich viel zu tun, wie Smart-Pointer: nichts. Wenigstens sind mir keine Smart-Pointer in Ada vorgekommen und 'Basis klassen getue' meine ich auch schon in Python gesehen zu haben.



  • Ich weiß, dass ich mit meiner Abneigung gegenüber typedefs ziehmlich allein dastehe. Das ändert aber nix dran, dass ich sie nur in äußersten Notfällen einsetze, wenn z.B. der Funktionspointertyp sonst gar so lang werden würde.
    Klar, sie sind praktisch, wenn man den Typ ändern will, aber ehrlich gesagt is mir das bis jetzt noch nicht so häufig vorgekommen, dass man projektweit nen Typ umstellen muss. Mach mir eigentlich immer sehr viele Gedanken, was für nen Typ ich nehmen muss. Und kommt natürlich daher, dass ich nur unter einem Compiler für Windoof progge. Mir also keine wirklichen Sorgen machen muss zwecks Größe der Typen - klar is vielleicht ziehmlich kurzsichtig und schlampig aber selbst wenn wir vom C-Builder auf VC umsteigen würden, hätten wir wohl keine probs damit und ich kann auch de fakto davon ausgehen, dass ein int auf einem 32-Bit-System 32 bit hat (klärt mich auf, gibts nen Compiler, wo das nicht so is) und dass das Teil maximal größer wird, nich aber kleiner.

    Ja und deswegen möchte ich wissen, ob das Teil ein std::auto_ptr oder ein boost::smart_pointer is
    Womit ich ja wissen müsste, wie diese Dinger intern aufgebaut sind. Das alles auf ein (vielleicht 3-zeichen-langen) Präfix zu reduzieren ist doch etwas waghalsig.

    Du arbeitest also mit den Dingern ohne zu wissen, wie sie intern aufgebaut sind? Sorry, aber mit smart-pointern KANN man nicht arbeiten, wenn man ihr kopierverhalten nicht kennt.
    Wie isses, benutzt ihr p für alle Arten von Zeigern? Wenn ich ein p sehe und kein delete dazu, werd ich misstrauisch (wenn doch, übrigens auch). Klar in c++-Code verwendet man keine rohen Zeiger aber leider kriegt man nicht immer reinen C++-Code vorgesetzt.
    Und was ist waghalsig daran? Ich weiß doch, dass ap ein std::auto_ptr is und xap is ne implementierunge eines referenzzählenden. In meinem Code ist das durchgängig so, und wer meinen Code liest, wirds auch recht schnell bemerken.

    Mich interesieren (wie schon öfters gesagt) die abstrakten Schnittstellen ('ich kann Addieren')

    Mich interessiert nicht nur, dass ich addieren kann, sondern mich interessiert auch, was beim Addieren schief gehn kann. Ein std::string könnte Speicherprobs produzieren, ein int nen überlauf. Und wenn ich ne Hausnummer hab. Was bedeuted dann addieren? 23+a gibt 23a oder is ein Fehler. 23+10 gibt 2310 oder 33? Klar, steht in der Doku der Hausnummern-Klasse. Aber beides hat seine Berechtigung, also immer in der Doku nachgucken. Oder man siehts eben gleich am Typ (obwohl ich Euch natürlich Recht gebe, wenn man Hausnummern addieren will, macht man dafür ne Klasse. Dann könnte man auch den +-Op für beide Fälle überladen).

    Gut, dann mach ich jetzt aus meinem strHausnummer ein z.
    Ändert an der Programmsemantik nichts.

    Natürlich änderts nix an der Programmsemantik. Aber an der Lesbarkeit und damit auch an der Qualität des Codes. Ach so, hier steht ja irgendwo: "man hat nen Compiler". Wiederspricht sich aber irgendwie mit sonst angebrachten Argument, dass man über Variablen mit vielen Präfixen mit keinem mehr reden kann.

    derived IST EIN base.
    'typeid (base) == typeid (derived)'?

    Es ist in der Objektorientierung definiert, dass es sich um eine "IST EIN"-Beziehung handelt. Typeid hingegen ist eine eindeutige Identifizierung für einen Typ. Das is eigentlich ein klarer Unterschied.

    Gleichheit ist insgesamt etwas komisch, nicht nur, was Computer anbetrifft ('das Gleiche' vs 'das Selbe').

    Gleichheit ist schlicht und einfach kontextabhängig, nicht komisch. Und "das Gleiche" hat auch eindeutig ne andere Bedeutung als "das Selbe". Is nunmal so.

    Und was der Mehraufwand für strenge Typisierung is, brauch ich wohl auch nich wirklich zu erklären: Es zwingt Dich, Dir gedanken zu machen, die Du Dir zwar auch ohne machen solltest, wo man aber leicht mal Leichtsinnsfehler begeht.

    ausserdem sollen sich Klassen wie normale Typen verhalten, so hat mans mir zumindestens beigebracht. warum sollte ich nun trennen?

    Die Regel "do it like the ints" is wie viele einfache Grundregeln schlichtweg viel zu pauschal. Klassen sollen sich nicht anders verhalten als normale Typen, da wo eine Unstimmigkeit entstehen kann (also z.B. operatoren). Aber ints haben schlichtweg keine Methoden und auch keinen derefenenzierungs-Op. Außerdem sind klassen spezialisierter als Basistypen. Gut, man könnte deswegen für jeden Basistypen ein typedef machen - je nach Zweck. Is aber imho aber unpraktisch und wenig sinnvoll, solange typedefs keine echten Typen sind.

    [ Dieser Beitrag wurde am 07.03.2003 um 10:29 Uhr von kartoffelsack editiert. ]

    [ Dieser Beitrag wurde am 07.03.2003 um 10:31 Uhr von kartoffelsack editiert. ]



  • Original erstellt von kartoffelsack:
    Du arbeitest also mit den Dingern ohne zu wissen, wie sie intern aufgebaut sind? Sorry, aber mit smart-pointern KANN man nicht arbeiten, wenn man ihr kopierverhalten nicht kennt.

    Ein gewisser Grad an Unwissen ist natürlich dabei, sonst könnte ich die Abstraktionsschicht 'Smart-Pointer' in die Tonne treten, respektive den Quelltext direkt hinschreiben. Um die Kopiersemantik zu kennen, genügt es vollkommen, die Kopiersemantik zu kennen :).

    Wie isses, benutzt ihr p für alle Arten von Zeigern?

    Nein. Keine Präfixe.

    Mich interessiert nicht nur, dass ich addieren kann, sondern mich interessiert auch, was beim Addieren schief gehn kann.

    Fehlerbehandlung findet nicht im 'normalen' Quelltext statt, wenn sie nicht lokaler Art sind. Weder 'Out of Memory' noch ein Integerüberlauf sind lokale Probleme.

    wenn ich ne Hausnummer hab. Was bedeuted dann addieren?

    Depends. Ich möchte zB über eine Straße iterieren. Also hat 8a+1 die nächste Hausnummer zu ergeben.

    Aber an der Lesbarkeit und damit auch an der Qualität des Codes.

    Und wenn ich aus z dann 'street_number' mache, dann passiert was? Aha! Es könnte also für jemanden, der seine Programme in Thai abfasst sinnvoll sein, seine Variable 'z' zu nennen, wenn 'z' gerade mal Hausnummer bedeutet.

    Ich finde übrigens 'z' nicht so schlecht zu lesen. Ich kann mir bloß nichts drunter vorstellen :).

    Typeid hingegen ist eine eindeutige Identifizierung für einen Typ.

    Warst es nicht Du, der den _genauen_ Typen wissen wollte? Immer?

    Gleichheit ist schlicht und einfach kontextabhängig

    Ja. Es verhält sich also nicht überall gleich und hat kein wirklich vorhersehbares Verhalten. Komisch :).

    Und "das Gleiche" hat auch eindeutig ne andere Bedeutung als "das Selbe".

    'Das Gleiche' hat schlichtweg überhaupt keine sinnvolle kontextfreie Bedeutung. Sind zwei grüne VW-Gölfe aus dem Jahre 1986 gleich?

    [strenge Typisierung] Es zwingt Dich, Dir gedanken zu machen, die Du Dir zwar auch ohne machen solltest, wo man aber leicht mal Leichtsinnsfehler begeht.

    Darf ich das so verstehen, dass man in schwächer getypten Sprachen mehr Leichtsinnsfehler wegen der Typen macht? Das glaube ich nicht. Ich kann mich wenigstens an keinen größeren Typenfehler in (deklarationsfreiem) Lisp erinneren.



  • <ot>

    Original erstellt von Daniel E.:
    Darf ich das so verstehen, dass man in schwächer getypten Sprachen mehr Leichtsinnsfehler wegen der Typen macht? Das glaube ich nicht. Ich kann mich wenigstens an keinen größeren Typenfehler in (deklarationsfreiem) Lisp erinneren.

    Ich weiß nicht ob du es so sagen wolltest, aber du behauptest implizit, dass Lisp schwach getypt ist. Lisp ist aber stark getypt.</ot>



  • Original erstellt von Daniel E.:
    Eine Basisklasse hat mit Typenprüfung ähnlich viel zu tun, wie Smart-Pointer: nichts. Wenigstens sind mir keine Smart-Pointer in Ada vorgekommen und 'Basis klassen getue' meine ich auch schon in Python gesehen zu haben.

    ich war der meinung das vererbung und co. dazu da ist das stare typen system kontroliert zu umgehen



  • Um die Kopiersemantik zu kennen, genügt es vollkommen, die Kopiersemantik zu kennen .

    Dann benutz ich das Präfix halt als Hinweis für die kopiersemantik. Da ich keine verschiedene smart-Pointer gleicher Kopiersemantik in einem Projekt verwende, entspricht sich das.

    Wie isses, benutzt ihr p für alle Arten von Zeigern?
    Nein. Keine Präfixe.

    *schluck* Mir wird schlecht, wenn ich bedenke, dass Essen.get() was anderes bedeuten könnte als Essen->get().

    Und wenn ich aus z dann 'street_number' mache, dann passiert was? Aha! Es könnte also für jemanden, der seine Programme in Thai abfasst sinnvoll sein, seine Variable 'z' zu nennen, wenn 'z' gerade mal Hausnummer bedeutet.

    Nachdem ich einmal in einem ganze Projekt alle Bezeichner auf Englisch übersetzen musste wegen ner neuen Kollegin, die kein Deutsch konnte, mach ichs immer auf Englich. Aber i.A. kann z natürlich sinnvoll sein, wenn man sich was drunter vorstellen kann. Und ich glaub auch nicht, dass Du diesen Punkt ernst meinst.

    Warst es nicht Du, der den _genauen_ Typen wissen wollte? Immer?

    Ich will den Typ so genau wissen, wie an dieser Stelle möglich.

    Darf ich das so verstehen, dass man in schwächer getypten Sprachen mehr Leichtsinnsfehler wegen der Typen macht? Das glaube ich nicht. Ich kann mich wenigstens an keinen größeren Typenfehler in (deklarationsfreiem) Lisp erinneren.

    Ich kenn Lisp nicht, aber ich denke, ich brauch Dir nicht zu erklären, was die Vorteile einer streng typisierten Sprache sind. Und unter schwach typisisert verstehe ich auch nicht deklarationsfrei sondern, dass der Compiler nicht verhindert, dass Du implizit schwachsinnige Casts machst.

    [ Dieser Beitrag wurde am 07.03.2003 um 12:11 Uhr von kartoffelsack editiert. ]



  • Was heißt stark/schwach, statisch/dynamisch in Bezug auf Typisierung:
    http://c2.com/cgi/wiki?TypingQuadrant http://www-lp.doc.ic.ac.uk/UserPages/staff/ft/alp/net/typing/strong.html



  • Original erstellt von Bashar:
    Ich weiß nicht ob du es so sagen wolltest, aber du behauptest implizit, dass Lisp schwach getypt ist. Lisp ist aber stark getypt.

    Lisp hat in erster Linie mal ein dynamisches Typenkonzept, C++ hat ein statisches. Das macht Vergleiche etwas komplizierter.

    Ich weiß nicht ob es Normen oder Standards für solche Begrifflichkeiten gibt, aber unter 'starker Typisierung' verstehe ich, dass mir Typenfehler (irgendwie definiert) abgefangen werden, und nichts Komisches passiert. De facto passiert sowas aber bei Common-Lisp nach einem '(declaim (optimize (safety 0) (speed 3)))' schon gerne mal.

    Original erstellt von Dimah:
    ]qb]ich war der meinung das vererbung und co. dazu da ist das stare typen system kontroliert zu umgehen[/qb]

    Sollte das jetzt 'starre' oder 'starke' heißen?
    Ich denke Vererbung ist nicht einfach nur ein grausiger Hack um Löcher in ein Typensystem zu stanzen.

    Original erstellt von kartoffelsack:
    **Ich will den Typ so genau wissen, wie an dieser Stelle möglich.
    **

    ... wie an dieser Stelle _nötig_. Dann sind wir uns einig :).



  • Die Konzepte stark/schwach und statisch/dynamisch sind orthogonal.

    Und nur weil Lisp es erlaubt, die Typprüfung auszuschalten, wird es noch nicht zu einer schwach getypten Sprache. Die Default-Einstellung ist safety 3, und das ändert man auch nicht einfach, solange die typenmäßige Korrektheit noch nicht klar ist.



  • wie an dieser Stelle _nötig_. Dann sind wir uns einig .

    Ne, ne, auf mein MÖGLICH besteh ich 😃 😉



  • Original erstellt von kartoffelsack:
    Ne, ne, auf mein MÖGLICH besteh ich 😃 😉

    dann musst du UN auch bei objekten verwenden.
    und konsequenterweise auch bei methoden und funktionen.



  • Ich versteh langsam den Sinn dieser Diskussion nicht mehr. Die die es machen machens und die die es nicht machen machens nicht 😃 . So einfach ist das. Wirklich überzeugen lässt sich in dem Punkt doch keiner...



  • Und dass das ändern länger dauert, weil man sich den Code durchgucken MUSS seh ich als Vorteil (man überlegt sich außerdem dann vielleicht vorher schon genauer, welcher Typ sinnvoll ist).

    naja, du siehst es als Vorteil, der andere nicht, dass ist sehr subjektiv. Objektiv kann man aber sagen, dass es mehr Aufwand ist (egal wie positiv das Ergebniss seien könnte). Weitere Aufwands Steigerung entstehen dadurch, dass man sich auf eine Notation festlegen muss, die in dem gesammten Projekt eingehalten werden sollte und gerade bei so Abkürzungen passieren leicht Fehler.

    Wenn ich ein p sehe und kein delete dazu, werd ich misstrauisch

    benutzt du nur Pointer, die auf dynamischen Speicher zeigen?

    Klar, steht in der Doku der Hausnummern-Klasse. Aber beides hat seine Berechtigung, also immer in der Doku nachgucken. Oder man siehts eben gleich am Typ

    Hä? Wie soll man das am Typ erkennen? Vielleicht weiss ich durch deine Notation, dass CHnummer eine Instanz der Klasse CHausnummer ist, aber deswegen kann ich keinen Rückschluß auf das Verhalten der Member von CHausnummer machen.


Anmelden zum Antworten