Ist es sinnvoll heute noch C++ anzufangen?



  • JustAnotherNoob schrieb:

    Erstmal zu audacia:

    cout.write ("foo").write (42).write (3.14159).write (endl);

    findest du das übersichtlich? Macht man in Java btw. auch nicht, da definiert man ja einen Sonderfall für +, weil es ja übersichtlicher ist den Operator zu überladen, aber natürlich nur in dem Fall. Es ist ja undenkbar, dass es sonst auch mal nützlich sein könnte.
    Hey fricky, wolltest du nicht ein Beispiel für sinnvolle Operatorenüberladung außerhalb mathematischer Bibliotheken? Wie wärs mit Stringconcatenation.
    Das ist ein Beispiel, wenn du auch nur annähernd logisch denken könntest wärst du auf den Gedanken gekommen, dass ein Beispiel schon ausreicht um zu legitimieren, dass man es benutzen kann aber nicht muss. Aber bitte, wenn du denkst, dass du nicht in der Lage bist auf Operatorenüberladung in sinnlosen Fällen zu verzichten, bitte.. dann ist Java vielleicht gut für dich, aber verweise hier bitte nicht auf Andere.

    Das Plus ist schlecht dafür und ich denke, dass Java das Plus auch nur hat, weil std::string es verwendet. Wer noch nie in einer Sprache programmiert hat in der das Plus für Stringkonkatenation steht, aber schon einmal etwas theoretische Informatik mitbekommen hat wird da sofort an das Oder aus einem regulären Ausdruck denken und nicht daran, dass hier eine Konkatenation gemeint ist.
    Schöner wäre es wie auch in Perl den Punkt zu benutzen, der kommt dem vertikal zentrierten Multiplikationspunkt am nächsten, der auch in der theoretischen Informatik meist für die Konkatenation benutzt wird. Aber den darf man in C++ ja aus guten Gründen nicht überladen, weshalb man sich dann wohl auf + geeinigt hat.



  • JustAnotherNoob schrieb:

    cout.write ("foo").write (42).write (3.14159).write (endl);

    findest du das übersichtlich?

    Nein. Übersichtlich finde ich das:

    printf ("foo %d %f", 42, 3.14159);
    


  • Dravere schrieb:

    +fricky schrieb:

    nicht verbieten, sondern garnicht erst einbauen, ...

    Und wo ist der Unterschied?

    verbieten = jemandem etwas untersagen, möglicherweise unter androhung von strafe oder ähnlichen konsequenzen.
    einbauen = etwas zu etwas anderem hinzufügen, so daß es bestandteil dessen wird.

    audacia schrieb:

    Das Lieblingsbeispiel von +-fricky ist, wenn ich mich recht erinnere, die Operatorpräzedenz.

    nein, der absolute c++ favorit von +fricky ist 'cout << x;' wobei x ein 'volatile int' grösser 1 ist. das ist richtig lustig und hat auch was mit überladung zu tun.

    Dravere schrieb:

    audacia schrieb:

    Zusätzlich versteht auch jeder C-Programmierer, daß es da nicht um Bitshifting geht

    Jetzt müssen wir schon eine Sprache wegen +fricky anpassen?

    nur das abschaffen der vergewaltigten shifts, würde mir aber lange nicht reichen.
    🙂



  • Also um mal auf das Ausgangsposting zurückzukommen, ich würde C++ heutzutage NICHT mehr einsetzen. Einen triftigen Grund gibt es für die Sprache nicht mehr, da hast du schon Recht. In den späten 80'ern und den 90'ern mag C++ sinnvoll gewesen sein, aber heutzutage gibt es einfach bessere Sprachen.

    Das Verhängnis von C++ ist halt, dass es eine Sprache für alles sein wollte und so weder am einen noch am anderen Ende die Bedürfnisse vernünftig zufriedenstellen kann. Der Lowlevel Entwickler meidet es, der Highlevel Entwickler ebenfalls.



  • quniox schrieb:

    Also um mal auf das Ausgangsposting zurückzukommen, ich würde C++ heutzutage NICHT mehr einsetzen. Einen triftigen Grund gibt es für die Sprache nicht mehr, da hast du schon Recht. In den späten 80'ern und den 90'ern mag C++ sinnvoll gewesen sein, aber heutzutage gibt es einfach bessere Sprachen.

    Das Verhängnis von C++ ist halt, dass es eine Sprache für alles sein wollte und so weder am einen noch am anderen Ende die Bedürfnisse vernünftig zufriedenstellen kann. Der Lowlevel Entwickler meidet es, der Highlevel Entwickler ebenfalls.

    ^^diese posting bringt alles auf den punkt 👍
    leute, wir können den thread hiermit als beendet betrachten
    🙂



  • Der Lowlevel Entwickler meidet es, der Highlevel Entwickler ebenfalls.

    Der Entwickler in der Praxis benutzt es. 🙄



  • +fricky schrieb:

    audacia schrieb:

    Das Lieblingsbeispiel von +-fricky ist, wenn ich mich recht erinnere, die Operatorpräzedenz.

    nein, der absolute c++ favorit von +fricky ist 'cout << x;' wobei x ein 'volatile int' grösser 1 ist. das ist richtig lustig und hat auch was mit überladung zu tun.

    Was passiert deiner Meinung nach denn in diesem Fall?



  • scheinbar ist es gerade der Kompromiß aus nicht bis in die letzte Konsequenz umgesetzten Prinzipien, die eine Sprache praxistauglich machen. Bei C++ die Mischung aus angedeuteter OO, mit low-level-features bei Bedarf sowie C-Kompatibilität. Reine OO unter Beibehaltung der C-Kompatibilität wäre wohl sowieso unmöglich. Objekte und Adreßarithmetik, Zeiger und GC, das paßt nicht.

    Paradigmenreine Sprachen haben dagegen mit Akzeptanzproblemen zu kämpfen oder gelten als ewige "Sprache der Zukunft", das war schon immer so und wird scheinbar auch so bleiben.

    "Die einen Sprachen werden gelobt, die anderen verwendet" - wer hat das gesagt? Ich weiß, wer etwas Ähnliches gesagt hat, hat sogar mit C++ zu tun.



  • nein, der absolute c++ favorit von +fricky ist 'cout << x;' wobei x ein 'volatile int' grösser 1 ist. das ist richtig lustig und hat auch was mit überladung zu tun.

    Gib mal einen Verweis auf den Standard, denn wenn das was seltsames machen soll, dann ist der GCC nicht Standardkonform, denn das hier:

    #include <iostream>
    
    using namespace std;
    
    int main()
      {
      volatile int i(2);
      cout << i;
      }
    

    gibt bei mir 2 aus.



  • sorry für die verwirrung, es muss natürlich ein pointer sein:

    volatile int *p = (volatile int*)0x1234;
        printf ("%p\n", p);  // ok
        cout << p << endl;   // 1?
    

    🙂



  • +fricky schrieb:

    sorry für die verwirrung, es muss natürlich ein pointer sein:

    volatile int *p = (volatile int*)0x1234;
        printf ("%p\n", p);  // ok
        cout << p << endl;   // 1?
    

    🙂

    Schönes Beispiel, will man allerdings die referenzierte Adresse ausgeben so *muss* man diesen nach void* casten. Damit will ich nicht behaupten, dass du unrecht hast, sondern, dass hier ein anderer Fallstrick vorliegt (jeder würde ja intuitiv erwarten, dass man einen Zeiger wie alles andere auch ausgeben kann).



  • +fricky schrieb:

    sorry für die verwirrung, es muss natürlich ein pointer sein:

    volatile int *p = (volatile int*)0x1234;
        printf ("%p\n", p);  // ok
        cout << p << endl;   // 1?
    

    🙂

    Wie sinnvoll ist es, den Wert eines Zeigers auszugeben? Ich sehe keinen praktischen Nutzen bzw. praktischen Nachteil darin. Da gibt es sicher andere interessante Konstrukte, um C++ zu kritisieren.

    Hier wird der Zeiger zur Ausgabe implizit in einen bool gecastet. Nicht unbedingt sinnvoll oder intuitiv, aber nicht wirklich problematisch.



  • Tippgeber schrieb:

    ...will man allerdings die referenzierte Adresse ausgeben so *muss* man diesen nach void* casten.

    aber seltsam: mit 'nem int*, ohne 'volatile' davor, gibts die erwartete (richtige) ausgabe auch ohne cast.

    tntnet schrieb:

    Wie sinnvoll ist es, den Wert eines Zeigers auszugeben? Ich sehe keinen praktischen Nutzen bzw. praktischen Nachteil darin.

    wenn man c++-fanboys zeigt, welch komische faxen mit ihrer sprache möglich sind, wird oft die sinnhaftigkeit der gesamten aktion in frage gestellt. woran liegts? selbstverständlich ist es manchmal sinnvoll, den wert eines zeigers auszugeben.

    tntnet schrieb:

    Da gibt es sicher andere interessante Konstrukte, um C++ zu kritisieren.

    ich weiss. manche füllen 90% ihres webauftritts damit.

    tntnet schrieb:

    Hier wird der Zeiger zur Ausgabe implizit in einen bool gecastet.

    was ja wohl das verkehrteste überhaupt ist.
    🙂



  • was ja wohl das verkehrteste überhaupt ist.

    Richtig, aber das hat mit Operatorenüberladung grad mal gar nix zu tun, wie du behaupted hast, sondern ist ein Nachteil der starken Typisierung, die 1. auch in deinem geliebtem Java existert und 2. mehr Vor- als Nachteile bringt.

    wenn man c++-fanboys zeigt, welch komische faxen mit ihrer sprache möglich sind, wird oft die sinnhaftigkeit der gesamten aktion in frage gestellt. woran liegts? selbstverständlich ist es manchmal sinnvoll, den wert eines zeigers auszugeben.

    wenn man einem java-fanboy zeigt, welche Dinge mit Java alles nicht möglich ist, wird oft die Sinnhaftigkeit der ganzen Aktion in Frage gestellt, woran liegts? Selbstverständlich ist es manchmal sinnvoll Operatoren zu überladen.



  • Allgemeiner Quark ...



  • JustAnotherNoob schrieb:

    Richtig, aber das hat mit Operatorenüberladung grad mal gar nix zu tun, wie du behaupted hast...

    indirekt schon. schliesslich versagt hier cout.operator<<() völlig und der benutzer wundert sich.

    JustAnotherNoob schrieb:

    sondern ist ein Nachteil der starken Typisierung, die 1. auch in deinem geliebtem Java existert und ...

    in einer stark typisierten sprache wäre ein cast von 'volatine int*' nach bool überhaupt nicht möglich. aber kannst gern mal selbst ausprobieren, was du in Java alles in einen boolean casten kannst.
    🙂



  • indirekt schon. schliesslich versagt hier cout.operator<<() völlig und der benutzer wundert sich.

    Das wäre bei einer anderen Funktion nicht anders, deswegen hats mit Operatorenüberladung nichts zu tun.

    in einer stark typisierten sprache wäre ein cast von 'volatine int*' nach bool überhaupt nicht möglich. aber kannst gern mal selbst ausprobieren, was du in Java alles in einen boolean casten kannst.

    Ja, sorry, mein Fehler. Es liegt jedenfalls an der stärkeren Typisierung als in C.
    Wie auch immer, es ist jedenfalls eine Schwäche von C++, aber keine, die man besonders oft zu spüren bekommt. Dass C++ perfekt ist hat wohl niemand behauptet.



  • JustAnotherNoob schrieb:

    indirekt schon. schliesslich versagt hier cout.operator<<() völlig und der benutzer wundert sich.

    Das wäre bei einer anderen Funktion nicht anders, deswegen hats mit Operatorenüberladung nichts zu tun.

    natürlich hat es damit zu tun. bei 'ner funktion: printThatFuckingPointerValue(void *p) siehste allein schon am namen, was sie machen soll. ein operator<< mit 1000 überladungen, der eigenmächtig (und fälschlicherweise) pointer in 'bools' castet, ist einfach nur mist.
    zu op-überladungen schau auch mal hier: http://cafe.elharo.com/blogroll/operator-overloading-considered-harmful/

    JustAnotherNoob schrieb:

    Dass C++ perfekt ist hat wohl niemand behauptet.

    das würd wohl auch keiner wagen, so weit wie C++ von perfektion entfernt ist.
    🙂



  • +fricky schrieb:

    natürlich hat es damit zu tun. bei 'ner funktion: printThatFuckingPointerValue(void *p) siehste allein schon am namen, was sie machen soll.

    Die würde aber nicht anwendbar sein für deinen volatile-Pointer. Außerdem müsstest du die Funktion print nennen und für genau dieselben Typen anwenden, für die du auch den operator<< anwendest. Du bist ja schließlich nur gegen Operatorüberladung, und nicht auch gegen Funktionsüberladung.
    Und dann würdest du feststellen, dass print(myvolatilepointer) auch den bool-Overload greift. IOW, das Problem hat mit Operatorüberladung überhaupt nichts zu tun.
    Es hat was mit der Semantik von volatile zu tun und wurde offenbar in der IOStreams-Library vergessen. Man bräuchte halt eine Überladung für const volatile void*, nicht nur const void*. 99% aller C++-Entwickler merken das aber nicht, weil man volatile nicht gerade jeden Tag braucht.

    ein operator<< mit 1000 überladungen, der eigenmächtig (und fälschlicherweise) pointer in 'bools' castet, ist einfach nur mist.
    zu op-überladungen schau auch mal hier: http://cafe.elharo.com/blogroll/operator-overloading-considered-harmful/

    Das ist ein Effekt der Überladung an sich, nicht der Operatorüberladung. Und in Java kann dir sowas natürlich nicht passieren, weils da weder const noch volatile noch Pointer überhaupt gibt, die man ausgeben wollen könnte.



  • Operatorüberladung ist ein Spezialfall von Polymorphie, und Polymorphie ist ein Prinzip der OOP.

    Das ist in C++ nur nicht so leicht zu erkennen, aber in der "reinen Lehre" der OO gibt es nur objects und messages, und ein Operatorsymbol ist nichts Anderes als eine message an ein object.

    Da gleichlautende Nachrichten an Objekte verschiedener Klassen nicht nur erlaubt, sondern sogar erwünscht (Polymorphie) sind, ist an der Operatorüberladung doch grundsätzlich nichts auszusetzen, solange die Symbole vernünftig gewählt werden (und nicht etwa "+" benutzt wird, um Elemente aus einer Liste zu entfernen ...)


Anmelden zum Antworten