welche vorteile bietet c++ gegenüber c



  • Volkard, irgendwie kenne ich dich noch nicht genug um beurteilen zu können, ob du nun mit mir oder gegen mich gesprochen hast 😃 Ich gehe in meiner positiven Weltanschauung einfach mal von ersterem aus, hehe.



  • Aber ich hatte schon oft die Situation, in der die Idee einfach war, aber unter dem Gesichtspunkt der "du hast ein Fehler in deinem Design"-Klatsche auf einmal zu einem wahren Akt wurde.

    Ich bin der Meinung, dass eine einfache Idee fast immer auch einfach zu implementieren ist.

    Wenn die Implementierung komplizierter wird, dann weil die Idee plötzlich wächst, z.B. indem neue Formen der Erweiterung, flexiblen Nutzung geschaffen werden. Und da C++ zum größten Teil eine Obermenge von C ist, kann C++ gar nicht schlechter sein. Möglicherweise wenden es die Entwickler aber fälscher an, weil sie C++ mit Java verwechseln oder so. 😛

    Alle Argumente gg. C++, die in die Richtung gehen, dass die Entwickler Mist bauen können, gehen für mich in Wahrheit gegen die Gründlichkeit der Einarbeitung der Entwickler.

    Und was noch dazu kommt, ist, dass C++ einem eigentlich viel Fehlerpotenzial abnimmt. Allein das Speichermanagement ist durch RAII/RRID doch so viel einfacher...

    Und dass man schneller zu einem Ergebnis kommt, liegt wohl auch einfach nur darin begründet, dass man in C weniger Konzepte verstehen muss. Wenn ich aber in C++ nicht auf ein sauberes Design erpicht bin, dann bastel ich mir schnell die Klassen für das Offensichtliche, packe die in irgendwelche Container zur Verwaltung und dann geht's halt los. Das ganze Geplane ist sowieso nur auf grober Ebene hilfreich, in den Details merkt man zu viel einfach erst, wenn man es implementiert.

    Gab es hier schon ein einziges Argument, hinter dem etwas mehr stand?



  • Was freigeist3 hier geschrieben hat halte ich für typisches gelaber von einem C++-Basher. Zuerst einmal die Tatsache, dass für C++ nur verbuggter Code existiert (was einfach nicht stimmt, deswegen gibt es hier wohl nicht viel zu argumentieren).
    Natürlich ist ein OOP-Design schwieriger, aber man muss, wie schon 1000 mal gesagt wurde, in C++ nicht Objektorientiert programmieren!
    Dadurch kann man auch dein Argument mit dem Schachprogramm entkräftigen, denn während du nur schnell etwas in C "hingesaut" hast, hat dein Freund wohl ein aufwendiges Design mit OOP geplant, welches ihm dann auch später, bei der Erweiterung des Programms, Vorteile gebracht hätte.
    Und jetzt kommt das lustige: Wenn dein Freund genauso vorgegangen wäre wie du, hätte er dich sogar schlagen können (gleiche Kompetenz und Erfahrung vorausgesetzt), da C++ z.B. die STL hat.
    Bei eurem Wettbewerb war es also nicht die Frage wer die bessere Sprache benutzt, sondern wer sauberer programmiert.



  • Also ich habe in RAII nie so wirklich viel Gewinn für mich gesehen, das hatte damals auch ohne gut geklappt. Richtig gut gebrauchen kann ich das ja erst mit dem In-den-Fuß-Schieß-Szenario mit Exception-Safety 😉 Also C++ hat es sozusagen auf der einen Seite schwieriger gemacht, aber mit dem Buzzword dann wieder vereinfacht 😉



  • Decimad schrieb:

    Also ich habe in RAII nie so wirklich viel Gewinn für mich gesehen, das hatte damals auch ohne gut geklappt.

    Nein. Dann hattest Du in C keine ordentliche Fehlerbehandlung. Man hat das gerne vernachlässigt damals. Deswegen waren Win3.1 und Word6 auch so abstürzig.
    Eine funktionierende Fehlerbehandlung in C bläst den gesamten Code um mindestens 50% auf. Durchgehend, und das nervt schon ungemein.



  • Decimad schrieb:

    Also ich habe in RAII nie so wirklich viel Gewinn für mich gesehen, das hatte damals auch ohne gut geklappt. Richtig gut gebrauchen kann ich das ja erst mit dem In-den-Fuß-Schieß-Szenario mit Exception-Safety 😉 Also C++ hat es sozusagen auf der einen Seite schwieriger gemacht, aber mit dem Buzzword dann wieder vereinfacht 😉

    Sry aber daraus kann man eigentlich nur schließen dass du RAII und Exceptions nicht verstanden hast...



  • Nunja, für das, was dort einen Absturz gab, würde ich ehrlich gesagt keine Exceptions verwenden, sondern den Quelltext robuster/fehlerfreier machen. Ich hab für mich nach Jahren gedanklich immer noch keinen goldenen Punkt gefunden, ab dem ich anerkenne, dass ein behandelbarer Fehler einer Exception würdig ist.



  • dot schrieb:

    Decimad schrieb:

    Also ich habe in RAII nie so wirklich viel Gewinn für mich gesehen, das hatte damals auch ohne gut geklappt. Richtig gut gebrauchen kann ich das ja erst mit dem In-den-Fuß-Schieß-Szenario mit Exception-Safety 😉 Also C++ hat es sozusagen auf der einen Seite schwieriger gemacht, aber mit dem Buzzword dann wieder vereinfacht 😉

    Sry aber daraus kann man eigentlich nur schließen dass du RAII und Exceptions nicht verstanden hast...

    Dann ist dem halt so - ich gewinne auch den Eindruck, mindestens schon weil ich es so oft an Orten verwendet sehe, bei denen ich mich fragen muss, ob es dort für mich Sinn ergibt!



  • Decimad schrieb:

    Nunja, für das, was dort einen Absturz gab, würde ich ehrlich gesagt keine Exceptions verwenden, sondern den Quelltext robuster/fehlerfreier machen. Ich hab für mich nach Jahren gedanklich immer noch keinen goldenen Punkt gefunden, ab dem ich anerkenne, dass ein behandelbarer Fehler einer Exception würdig ist.

    Wenn die GDI-Ressourcen aufgebraucht sind, kann man abstürzen lassen (also typische C-Fehlerbehandlung, nämlich gar keine), oder man kann mit exit() raus (also nicht das Dokument abspeichern, naja, wenigstens keine korrupten Daten). Oder viel viel Arbeit reinstecken. Viel.
    Oder man nimmt C++.
    Zuverlässige Destruktoren sind für mich der Grund, weshalb ich lieber in Perl schreibe als in PHP.



  • Eisflamme schrieb:

    Und dass man schneller zu einem Ergebnis kommt, liegt wohl auch einfach nur darin begründet, dass man in C weniger Konzepte verstehen muss.

    Ja, aber viele moderne C++ Experten verstehen ja nichtmal diese grundlegenden
    (prozeduralen) Konzepte, weil sie von den 'modernen' Lehrbüchern sofort ins
    kalte C++ Wasser geworfen werden, wo der Tanz (OOP, Templates) vor dem
    aufrechten Gang (Schleifen, Funktionen) gelehrt wird, also kurzerhand jene
    Teilmenge von C++, die über C hinaus geht, falscher Weise zuerst durchgenommen
    wird. Braucht man ja nur ins C++ Unterforum gucken, wo die Leute zwar brav
    mit <vector>, <boost> usw. arbeiten, aber so ihre liebe Not mit dem Vertauschen
    von Variablenwerten oder dem Finden einzelner Zeichen in einem String
    haben, also wo die elementarsten Operationen zum Problem werden.
    Also mich wundert's angesichts dieses Umstands kaum, dass moderne C++ Software
    typischer Weise erst nach dem 1000. Bugfix halbwegs das tut, was sie soll:
    Weil die Entwickler ja oft C++ vor (und nicht selten sogar anstelle)
    des eigentlichen Programmierens (aka algorithmisches Denken)
    gelernt haben.

    @volkard
    Mein Freund ist mittlerweile dazu übergegangen, mehrere Funktionen meiner
    C-Engine für seine C++ Engine zu wrappen und auf dieser Basis weiter zu
    arbeiten (was übrigens sowieso die typische Vorgangsweise in C++ zu sein
    scheint: Bereits existierende, gut implementierte C-Funktionen/Module neu zu
    'verkleiden' und das Resultat dann als coole C++ Lösung zu bezeichnen.
    Das fängt schon alleine damit an, dass man sich dutzende neue Namen für
    den elementaren Zuweisungsoperator ausdenkt:
    Klassen-Getter() und Setter() - und sich dann einredet, man hätte ebenso viele Funktionen 'neu' erfunden, wie man Getter und Setter hat.
    Was für eine Errungenschaft! Diese coole Kapselung von Klassen-Members ist
    ja schon ein Beispiel für die generelle C++ Tendenz, die elementarsten Räder
    auf zigfache Weise immer wieder auf's neue zu erfinden, neu zu benennen, und
    insgesamt nicht recht viel mehr zuwege zu bringen als sich neue Namen für
    allerlei - bereits existierende - Funktionen auszudenken.
    Die sinnvolle Kombination elementarer Operationen (Zuweisung z.B.)
    zu zunehmend komplexeren Prozeduren und Funktionen ist ja veraltet und hat
    in C++ nix verloren, hehe. Dazu wird's wohl noch für geraume Zeit so naive
    C-Arbeiter geben müssen, damit die C++ Leutchen was haben, das sie in ihre
    Klassen verpacken können.
    mfg



  • Inwiefern vereinfacht mir denn nun eine Exception das Freilassen aller nicht zwingend benötigten (Beispielsweise Caches) GDI-Ressourcen um es nochmal zu probieren? Hast du da irgendwo ein Produktiv-Beispiel? Vielleicht erkenne ich dann ja die mir verborgene Simplizität und Eleganz! Am besten natürlich eine Gegenüberstellung, die anschließend generalisiert wird, natürlich.



  • freigeist3 schrieb:

    Eisflamme schrieb:

    Und dass man schneller zu einem Ergebnis kommt, liegt wohl auch einfach nur darin begründet, dass man in C weniger Konzepte verstehen muss.

    Ja, aber viele moderne C++ Experten verstehen ja nichtmal diese grundlegenden
    (prozeduralen) Konzepte, weil sie von den 'modernen' Lehrbüchern sofort ins
    kalte C++ Wasser geworfen werden, wo der Tanz (OOP, Templates) vor dem
    aufrechten Gang (Schleifen, Funktionen) gelehrt wird, also kurzerhand jene
    Teilmenge von C++, die über C hinaus geht, falscher Weise zuerst durchgenommen
    wird. Braucht man ja nur ins C++ Unterforum gucken, wo die Leute zwar brav
    mit <vector>, <boost> usw. arbeiten, aber so ihre liebe Not mit dem Vertauschen
    von Variablenwerten oder dem Finden einzelner Zeichen in einem String
    haben, also wo die elementarsten Operationen zum Problem werden.
    Also mich wundert's angesichts dieses Umstands kaum, dass moderne C++ Software
    typischer Weise erst nach dem 1000. Bugfix halbwegs das tut, was sie soll:
    Weil die Entwickler ja oft C++ vor (und nicht selten sogar anstelle)
    des eigentlichen Programmierens (aka algorithmisches Denken)
    gelernt haben.

    @volkard
    Mein Freund ist mittlerweile dazu übergegangen, mehrere Funktionen meiner
    C-Engine für seine C++ Engine zu wrappen und auf dieser Basis weiter zu
    arbeiten (was übrigens sowieso die typische Vorgangsweise in C++ zu sein
    scheint: Bereits existierende, gut implementierte C-Funktionen/Module neu zu
    'verkleiden' und das Resultat dann als coole C++ Lösung zu bezeichnen.
    Das fängt schon alleine damit an, dass man sich dutzende neue Namen für
    den elementaren Zuweisungsoperator ausdenkt:
    Klassen-Getter() und Setter() - und sich dann einredet, man hätte ebenso viele Funktionen 'neu' erfunden, wie man Getter und Setter hat.
    Was für eine Errungenschaft! Diese coole Kapselung von Klassen-Members ist
    ja schon ein Beispiel für die generelle C++ Tendenz, die elementarsten Räder
    auf zigfache Weise immer wieder auf's neue zu erfinden, neu zu benennen, und
    insgesamt nicht recht viel mehr zuwege zu bringen als sich neue Namen für
    allerlei - bereits existierende - Funktionen auszudenken.
    Die sinnvolle Kombination elementarer Operationen (Zuweisung z.B.)
    zu zunehmend komplexeren Prozeduren und Funktionen ist ja veraltet und hat
    in C++ nix verloren, hehe. Dazu wird's wohl noch für geraume Zeit so naive
    C-Arbeiter geben müssen, damit die C++ Leutchen was haben, das sie in ihre
    Klassen verpacken können.
    mfg

    Soviel Ahnung vom Programmieren wie Du hatte ich nach sechs Wochen. Du bist einfach noch nicht so weit, mitzureden.



  • Du

    Mein Freund ist mittlerweile dazu übergegangen, mehrere Funktionen meiner
    C-Engine für seine C++ Engine zu wrappen und auf dieser Basis weiter zu
    arbeiten (was übrigens sowieso die typische Vorgangsweise in C++ zu sein
    scheint: Bereits existierende, gut implementierte C-Funktionen/Module neu zu
    'verkleiden' und das Resultat dann als coole C++ Lösung zu bezeichnen.

    bist

    Das fängt schon alleine damit an, dass man sich dutzende neue Namen für
    den elementaren Zuweisungsoperator ausdenkt:
    Klassen-Getter() und Setter() - und sich dann einredet, man hätte ebenso viele Funktionen 'neu' erfunden, wie man Getter und Setter hat.
    Was für eine Errungenschaft!

    so was von

    Diese coole Kapselung von Klassen-Members ist
    ja schon ein Beispiel für die generelle C++ Tendenz, die elementarsten Räder
    auf zigfache Weise immer wieder auf's neue zu erfinden, neu zu benennen, und
    insgesamt nicht recht viel mehr zuwege zu bringen als sich neue Namen für
    allerlei - bereits existierende - Funktionen auszudenken.

    raus. 😃



  • Decimad schrieb:

    Inwiefern vereinfacht mir denn nun eine Exception das Freilassen aller nicht zwingend benötigten (Beispielsweise Caches) GDI-Ressourcen um es nochmal zu probieren?

    Beim Stack-Unwinding werden Destruktoren aufgerufen. Wenn Du dem Catcher sagen willst, er soll es in ein paar Sekunden nochmal probieren, kannste ihm auch sagen, daß er Caches löschen soll.
    Aber mir hätte es schon gereicht, die Daten ohne weitere Anzeige zu speichern, eventuelle Datenbankverbindungen zu schließen, Datei-Locks freizugeben, den Video-Modus zurückzusetzen, Netzwerkverbindungen zu trennen, ganz einfache Sachen, die ganz lästig sind, wenn man sie nicht macht.



  • Das Guttenberg unter den Programmen sozusagen, der geordnete Abgang! Nee, das sehe ich 1:1 ein, das ist okay. Ob man mit der GDI Probleme bekommt, oder dem Speicher, liegt ja auch bei fehlerfreiem Programmablauf oft nicht in der eigenen Hand. Aber diese ganzen DivisionByZero-Exceptions in den Algorithmen usw. kann ich eben nicht so ganz nachvollziehen.



  • volkard schrieb:

    Decimad schrieb:

    Inwiefern vereinfacht mir denn nun eine Exception das Freilassen aller nicht zwingend benötigten (Beispielsweise Caches) GDI-Ressourcen um es nochmal zu probieren?

    Beim Stack-Unwinding werden Destruktoren aufgerufen.

    Hmm, sind das nicht die Destuktoren, die selbst keine Exceptions werfen sollten? Weil wenn Sie das tun, undefiniertes Verhalten auftritt bzw. die Desktruktion einer Objekthierarchie kaputt geht? Also wäre es eigentlich sinnvoll eine "public: void ReleaseResources()"-Methode zu machen, damit man im Fall einer Exception beim Freigeben von Ressourcen noch handeln kann. Wer ruft die optimalerweise auf? Der Destruktor der Klasse? Der müsste dann die Exception schlucken, wenn er sie nicht behandeln kann. Unschön. Oder doch Clientcode? Dann geben wir das Schicksal in externe Hände.



  • Decimad schrieb:

    Aber diese ganzen DivisionByZero-Exceptions in den Algorithmen usw. kann ich eben nicht so ganz nachvollziehen.

    Viele libs werfen grotesk viele Exceptions. Das kann man in Java machen. In C++ sollte man sie sparsam einsetzen.
    Zum Beispiel eineEmptyStackException wäre in Java Katastrophe.

    Eine DivisionByZero kann Sinn ergeben, zum Beispiel wenn der Matrizeninvertierer mitten im Rechnen feststllt, daß sie nicht invertierbar war. Ich könnte auch stur weiterrechnen, aber dann müßte ich nachher nochmal über die ganze Matrix laufen und schauen, daß nirgend NAN oder INF aufgetaucht ist.

    Oder die Invertierfunktion gibt irgendwie anders zurück, ob's geklappt hat. Zusätzlicher Parameter oder zwei Rückgaben? Nicht hübsch. Das Matrixformat ändern, daß sie auch sowas wie NAN darstellen kann. Hmm, wenn es angemessen ist, mag es einen Versuch wert sein. Aber hier tendiere ich eher zu Exception, klingt einfach schneller als überall mit if zu hantieren und zu prüfen. Und in Zusammenhängen, wo es fast immer klappt, kann ich hübsch die Füße hochlegen und nur in der main() fangen, und trotzdem geht mir kein Rechenfehler durch die Lappen.



  • Ich versteh gerade nicht, wieso irgend ein dtor sowieso eine Exception werfen können sollte. Das würde ich aus der Problematik heraus gar nicht erst erlauben. Wenn irgendwas nicht gelöscht werden kann, dann ist das eben Pech und wird evtl. noch irgendwo reingeschrieben (und wenn die entsprechende Datei nicht geöffnet wird, dann eben auch da nicht). Wenn ein dtor seinen Speicher nicht freigeben kann, wie will man so etwas denn sinnvoll behandeln? Das kann dann ja die Runtime bzw. das BS übernehmen...

    Darf im Stack-Unwinding-Prozess eigentlich auch keine Ausnahme lokal erzeugt und gefangen werden? Sodass im dtor try{bla}catch(...){} steht? Dafür sähe ich gewisse Anwendung, wenn so was eben Mal passieren kann. Oder geht das auch nicht?



  • GPC schrieb:

    Hmm, sind das nicht die Destuktoren, die selbst keine Exceptions werfen sollten?

    Das sind die Fälle, wo meine Programme fehlerhaft sind. Also Platte zu 100% voll => es wird bei kritischem Fehler nicht mehr korrekt gespeichert UND der Benutzer sieht es nicht. Er würde keine Messagebox bekommen, wenn die Datenbankverbindung oder andere Netzwerkverbindung nicht geschlossen werden könnte oder der Videomodus nicht zurückgesetzt werden könnte. Das hat mich noch nicht genervt.

    GPC schrieb:

    void ReleaseResources()

    Nein, die heilt gar nichts.

    GPC schrieb:

    Oder doch Clientcode? Dann geben wir das Schicksal in externe Hände.

    Ich weiß nicht, was hiermit gemeint ist.



  • volkard schrieb:

    GPC schrieb:

    Hmm, sind das nicht die Destuktoren, die selbst keine Exceptions werfen sollten?

    Das sind die Fälle, wo meine Programme fehlerhaft sind. Also Platte zu 100% voll => es wird bei kritischem Fehler nicht mehr korrekt gespeichert UND der Benutzer sieht es nicht. Er würde keine Messagebox bekommen, wenn die Datenbankverbindung oder andere Netzwerkverbindung nicht geschlossen werden könnte oder der Videomodus nicht zurückgesetzt werden könnte. Das hat mich noch nicht genervt.

    Im Endeffekt heißt das einfach, dass dann halt business as usual gemacht wird, wenn der Destruktor Ressourcen nicht korrekt freigeben konnte? 🙂
    Bzw. sich das Problem dahingehend ausdehnt, dass man in Destruktoren keine Funktionen aufrufen sollte, die eine Exception werfen könnte.

    GPC schrieb:

    void ReleaseResources()

    Nein, die heilt gar nichts.

    Offensichtlich kann man sich auf Destruktoren aber auch nicht verlassen.

    GPC schrieb:

    Oder doch Clientcode? Dann geben wir das Schicksal in externe Hände.

    Ich weiß nicht, was hiermit gemeint ist.

    Dass der Code, der deine Klasse benutzt, dafür verantwortlich ist, dass auch Exceptions in solchen Release-Methoden gehandelt wird, da der Destruktor es nicht kann.

    Durch das Stack-Unwinding geht btw. auch der Call stack verloren 👍


Anmelden zum Antworten