NULL



  • JustAnotherNoob schrieb:

    Ich hatte z.B. mal eine Klasse implementiert, die wie ein Pointer zu handhaben ist, sich aber aus einem Funktor konstruiert und den eigentlichen Inhalt damit erst läd, wenn dieser benötigt wird(sprich annähernd das was unter Haskell lazy evaluation bewerkstelligt). Sowas könnte man auch unter Java gebrauchen.

    im prinzip steuert das ein flag, dass vor dem ersten zugriff false ist, die daten beim ersten zugriff lädt und dann auf true gesetzt wird, stimmts? wieso hast du die klasse denn als pointer getarnt, wenn sie doch keiner ist? und dass sie sich in jedem fall wie ein echter pointer verhält, will ich mal bezweifeln. das bekommste wahrscheinlich trotz aller operatorenüberladungen nicht hin.

    JustAnotherNoob schrieb:

    Joa, Spezialfälle wie Inline-EBNF und Inline-RegExp bleiben.

    was meinst du mit 'inline'? dinge die der compiler selbst auswertet, ohne code zu erzeugen, der zur laufzeit (z.b. die RegExp) ausgeführt wird? wenn ja: stimmt, sowas kann java nicht (empfinde ich übrigens nicht als nachteil). java hat noch nicht mal sowas ähnliches wie den C-präprozessor. wer code-manipulierende features o.ä. braucht, ist auf zusatztools wie externe codegeneratoren usw. angewiesen.

    ...aber ich bezweifle, dass jemand, der Bescheid weiß mal aus Versehen Operatorenüberladung verwendet.

    nicht aus versehen, für den verfasser verständlich und einleuchtend, für andere leser (und verwender) des codes möglicherweise schwer durchschaubar und mit seltsamen nebeneffekten verbunden. z.b. haste das problem bei 'nem überladenen operator, wer das resultat wieder freigeben soll, wenn's nicht mehr gebraucht wird. oder was passiert, wenn die operation schiefgeht usw. d.h. du musst dir viele gedanken machen, wenn du op-overloading sinnvoll einsetzen willst, damit der benutzer es intuitiv verwenden kann, ohne in irgendwelche fallen zu tapsen. der aufwand steht nicht im verhältnis zum nutzen (es sei denn, man hat spass an sowas).
    🙂



  • JustAnotherNoob schrieb:

    meinst C++ Refrenzen? Soweit ich weiß nicht. Deswegen sagte ich, dass für mich Java Referenzen eher wie C++ Referenzen sind und nicht wie C Zeiger.

    => Bei Java Referenzen kannst du das aber.

    geht bei Java sowas auch?

    uint32_t *device = (uint32_t*) 0xdeadbeef?
    


  • Nö, das war auch nicht die Aussage.
    Die Aussage war, dass Java-Referenzen beschränkte C++ Zeiger sind, aber noch wesentlich näher an C++ Zeigern, als an C++ Referenzen und dass Java Referenzen im nachhinein umgebogen werden können, sprich auf andere Objekte zeigen, als auch ungültig(auf 0(/null) zeigen) können.

    Zumal denke ich sollte man nicht nur die technischen Eigenschaften vergleichen, sondern vor allem die Anwendung. Da so etwas wie in deinem Beispiel nicht mal aus Versehen vorkommt wirst du hier auch keine potenzielle Fehlerquelle finden, weswegen es ziemlich sicher ist so etwas zuzulassen. Pointer-Arithmetik jedoch ist genau der Unterschied zwischen Java-Referenzen und C++-Zeigern, aber die verwendest du auch nicht einfach mal so aus Versehen, da kannst du ebenso drauf verzichten, wenn du sie nicht willst..



  • letztendlich wird ja beides - Referenz wie Zeiger - in der CPU auf das selbe abgebildet, nämlich auf eine Speicherzelle zur Speicherung der Adresse, auf die dann mit indirekter Adressierung zugegriffen wird.

    btw. Wie würde man denn in C++ ein File öffnen, ohne Zeiger zu verwenden?



  • JustAnotherNoob schrieb:

    Da so etwas wie in deinem Beispiel nicht mal aus Versehen vorkommt wirst du hier auch keine potenzielle Fehlerquelle finden, weswegen es ziemlich sicher ist so etwas zuzulassen.

    in Java vielleicht, aber in C oder C++ muss man das manchmal machen, um bestimmte Geräte anzusprechen. Aber ich hab jetzt verstanden, worauf du hinaus willst.



  • supertux schrieb:

    geht bei Java sowas auch?

    uint32_t *device = (uint32_t*) 0xdeadbeef?
    

    nö, aus verschiedenen gründen nicht.
    - pointer wie in C gibts nicht.
    - ein nackter 'int' lässt sich nicht zu 'ner objektreferenz casten.
    - adressen im sinne von C (wo befindet sich was im speicher) gibts in Java nicht.
    also, alles was irgendwie maschinennah ist, wurde bei Java bewusst weggelassen.

    achso, noch mal 'ne frage zu c++ operatorüberladung: angenommen ich mache mir mit C++ 'ne klasse, die sinnvoll überladene shift-operatoren haben könnte (z.b. eine art schieberegister-simulation). kann ich den << zusätzlich noch als 'stream-output' operator überladen. ich meine ungefähr so:

    LFSR lfsr; // das register
    lfsr = lfsr << 93;  // ein paar takte weitertickern (überladener op)
    cout << lfsr << endl;   // momentanen zustand ausgeben (überladener op)
    

    ^^oder geht sowas nicht? müsste doch eigentlich. der compiler könnte ja erkennen, dass der zweite operand ein 'int' ist.
    🙂



  • im prinzip steuert das ein flag, dass vor dem ersten zugriff false ist, die daten beim ersten zugriff lädt und dann auf true gesetzt wird, stimmts? wieso hast du die klasse denn als pointer getarnt, wenn sie doch keiner ist? und dass sie sich in jedem fall wie ein echter pointer verhält, will ich mal bezweifeln. das bekommste wahrscheinlich trotz aller operatorenüberladungen nicht hin.

    Erstens einmal wüsste ich gerne wo du da einen Flag brauchst...
    Zweitens sehe ich nicht, was du mit "als Pointer tarnen" meinst, die Klasse verhält sich semantisch wie ein Smartpointer - ob mir das perfekt gelungen ist, hat nichts damit zu tun, dass es möglich ist. Wozu das gut ist? Ich habe erst letztens wieder ein paar shared_ptr durch diese Klasse ersetzt ohne Code ändern zu müssen, in Java hätte ich wieder an dutzenden Stellen den Code gebrochen.
    Templates gibt es in Java nicht, deswegen verfehlt es diese Diskussion ein wenig, waren aber auch ein Argument für diese Syntax.

    in Java vielleicht, aber in C oder C++ muss man das manchmal machen, um bestimmte Geräte anzusprechen.

    Will eigentlich sagen, immer wenn es in Java ohne geht, geht es in C++ auch ohne.

    ist auf zusatztools wie externe codegeneratoren usw. angewiesen

    der aufwand steht nicht im verhältnis zum nutzen.

    fällt dir was auf?

    edit:

    achso, noch mal 'ne frage zu c++ operatorüberladung: angenommen ich mache mir mit C++ 'ne klasse, die sinnvoll überladene shift-operatoren haben könnte (z.b. eine art schieberegister-simulation). kann ich den << zusätzlich noch als 'stream-output' operator überladen. ich meine ungefähr so:

    Ja das geht. Sind ja ganz normale Funktionen, die überladen werden können.



  • JustAnotherNoob schrieb:

    Erstens einmal wüsste ich gerne wo du da einen Flag brauchst...

    ich schrieb ja 'im prinzip'. irgendwo muss das ding doch seinen zustand speichern.

    JustAnotherNoob schrieb:

    Zweitens sehe ich nicht, was du mit "als Pointer tarnen" meinst, die Klasse verhält sich semantisch wie ein Smartpointer

    damit meine ich, dass eine klasse, die steuert wann daten verfügbar sind, von einem 'pointer' ziemlich weit entfernt ist. die funktionalität ist sinnvoll, aber das ganze als pointer zu kaschieren, hört sich für mich zumindest fragwürdig an.

    JustAnotherNoob schrieb:

    Wozu das gut ist? Ich habe erst letztens wieder ein paar shared_ptr durch diese Klasse ersetzt ohne Code ändern zu müssen, in Java hätte ich wieder an dutzenden Stellen den Code gebrochen.

    nö, in Java benutzt man dafür interfaces. dann kannste die implementation dahinter leicht austauschen. übrigens hast du einen workaround (verzögertes laden, weil shared-ptr das nicht hergibt) für einen workaround (klasse gibt sich als pointer aus, weil automatisches speichermanagement u.ä. fehlt) gebaut. aber ok, das ist wohl unter C++ eine akzeptable lösung.

    Ja das geht. Sind ja ganz normale Funktionen, die überladen werden können.

    aha, danke. dass op's in c++ funktionen sind, wusste ich noch. nur dass man sie mehrfach überladen kann, ist mir entfleucht.
    🙂



  • +fricky schrieb:

    ...aber ich bezweifle, dass jemand, der Bescheid weiß mal aus Versehen Operatorenüberladung verwendet.

    nicht aus versehen, für den verfasser verständlich und einleuchtend, für andere leser (und verwender) des codes möglicherweise schwer durchschaubar und mit seltsamen nebeneffekten verbunden. z.b. haste das problem bei 'nem überladenen operator, wer das resultat wieder freigeben soll, wenn's nicht mehr gebraucht wird. oder was passiert, wenn die operation schiefgeht usw. d.h. du musst dir viele gedanken machen, wenn du op-overloading sinnvoll einsetzen willst, damit der benutzer es intuitiv verwenden kann, ohne in irgendwelche fallen zu tapsen.

    Freigegeben wird alles automatisch, beim Fehler fliegt 'ne Exception. Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").


  • Administrator

    Vielleicht sollte fricky mal diesen Artikel lesen:
    http://magazin.c-plusplus.net/artikel/%DCberladung%20von%20Operatoren%20in%20CPlusPlus%20(Teil%201)

    Allerdings erscheint mir die ganze Diskussion sowieso ein wenig überflüssig zu sein. Hier kommen überall Argumente von Leuten, welche sich mit der Sprache, über welche sie argumentieren, so gut wie nicht beschäftigt haben. fricky ist meiner Meinung nach der beste Kandidat für so eine Person 😉

    C++ ist nicht perfekt, C ist nicht perfekt und Java ist nicht perfekt. Damit wäre die Diskussion eigentlich schon zusammengefasst. Ah, nein, habe was vergessen. Die fanatischen Anhänger der Sprachen denken jeweils, dass ihre Sprache besser wäre, als die anderen. So, jetzt ist es zusammengefasst 🤡

    Grüssli



  • +fricky schrieb:

    C++ aber auch nicht, hat's alles von C übernommen, bis auf die kleine ausnahme mit dem void*
    🙂

    Haha, Du kennst C++ doch gar nicht richtig!



  • supertux schrieb:

    Oder kannst du eine Java Referenz auf jede beliebige Addresse des Addressraums zeigen lassen?

    Java Referenzen folgen der Semantik und Syntax der Pascal-Zeiger! Man kann lediglich keine Zeigerarithmetik wie in C machen, was per se kein Nachteil ist. Typsicherheit gilt für Zeiger (Java Referenzen) ebenfalls, aber das trifft auf andere Sprachen mit Zeiger auch zu.



  • +fricky schrieb:

    nö, in Java benutzt man dafür interfaces.

    Interfaces sind Mehrfachvererbung für Arme. Wenn man ein SmartPointer verwendet hat man keine Abhängigkeit im Sinne "erbt von" sondern "beinhaltet". Java muß man da auch Zeiger (Referenzen) verwenden. Bei Fowler & Co. finden sich Hinweise zum passenden Entwurf von Klassen.



  • +fricky schrieb:

    achso, noch mal 'ne frage zu c++ operatorüberladung: angenommen ich mache mir mit C++ 'ne klasse, die sinnvoll überladene shift-operatoren haben könnte (z.b. eine art schieberegister-simulation). kann ich den << zusätzlich noch als 'stream-output' operator überladen. ich meine ungefähr so:

    Ja, das geht problemlos, da die Typen der Argumente unterschiedlich sind.

    Den operator<< definiert man üblicherweise als reine Funktion, man kann ihn auch als Methode definieren, aber das hat andere Vor-/Nachteile.



  • Badestrand schrieb:

    Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").

    ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.

    ~john schrieb:

    +fricky schrieb:

    C++ aber auch nicht, hat's alles von C übernommen, bis auf die kleine ausnahme mit dem void*
    🙂

    Haha, Du kennst C++ doch gar nicht richtig!

    es ging um's typsystem. c++ hat so gut wie nichts, was die typisierung sicherer macht, als von die von C. beide sprachen sind schwach typisiert.

    ~john schrieb:

    +fricky schrieb:

    nö, in Java benutzt man dafür interfaces.

    Interfaces sind Mehrfachvererbung für Arme.

    nenn es wie du willst. interfaces sind praktisch, wenn man verschiedene implementierungen für ähnliche dinge hat. du kannst damit festlegen, was ein objekt können soll, ohne konkret angeben zu müssen, um welches klasse von objekten es sich handelt.

    ~john schrieb:

    Wenn man ein SmartPointer verwendet hat man keine Abhängigkeit im Sinne "erbt von" sondern "beinhaltet". Java muß man da auch Zeiger (Referenzen) verwenden.

    wer redet hier von vererbung (ausser dir)? sicherlich verwendet java auch zeiger bzw. referenzen (sind ja sowieso das selbe), aber die brauchen nicht 'smart', sondern können ruhig ganz dumm sein, ohne das irgendwas schlimmes passiert.
    🙂



  • +fricky schrieb:

    Badestrand schrieb:

    Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").

    ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.

    Die Stream-Operatoren zur Ausgabe sind in C++ doch intuitiv. '^' für pow ist natürlich ein Fehltritt.



  • Badestrand schrieb:

    +fricky schrieb:

    Badestrand schrieb:

    Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").

    ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.

    Die Stream-Operatoren zur Ausgabe sind in C++ doch intuitiv. '^' für pow ist natürlich ein Fehltritt.

    '^' für pow wäre auch intuitiv. wenn die meisten es machen würden, wäre es was ganz normales. blöd dabei ist aber, dass die rangfolge von operatoren beim überladen nicht geändert werden kann. das hat der erfinder von C++ einfach vergessen.
    🙂



  • +fricky schrieb:

    Badestrand schrieb:

    Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").

    ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.

    Link, falls es bei der in der Firma passiert ist, poste es bitte auf thedailywtf.com



  • +fricky schrieb:

    blöd dabei ist aber, dass die rangfolge von operatoren beim überladen nicht geändert werden kann. das hat der erfinder von C++ einfach vergessen.

    Du wetterst gegen Operatorüberladung weil es den Code ja achso unleserlich macht und willst aber ganz elementare Eigenschaften dieser gleich auch noch ändern können? Ich weiss ja dass du nur trollst, aber etwas weniger offensichtlich bitte 😉



  • Tim schrieb:

    Du wetterst gegen Operatorüberladung weil es den Code ja achso unleserlich macht und willst aber ganz elementare Eigenschaften dieser gleich auch noch ändern können?

    naja, es wäre doch 'ne verbesserung. dann könnte man dafür sorgen, dass ein überladener '^'-operator vor +,-,*,/, usw. kommt und ihn damit als 'pow' nutzen. die shifts werden doch auch schon anderweitig verwendet, ohne dass sich jemand dran stört.
    🙂


Anmelden zum Antworten