Verleitet C++ zum komplizierteren denken?



  • Ich finde nicht dass C++ zu komplizietem Denken vereleitet. Ich programmiere seit etwa 5 Jahren in C++. Das wäre mir aufgefallen



  • Hier wird z.B. das OO-Prinzip "Datenkapselung" nicht unterstützt:

    es gibt einen Unterschied zwischen Unterstützen und Erzwingen.

    In C++ gibt es aber trotzdem keine Kapselung im OOP-Stil, weil alle private member der Klasse oeffentlich bekannt sind und jede Aenderung an den private members eine Aenderung des Client-Codes noetig macht (man muss den Client-Code neu uebersetzen).

    Diese Aussage trifft nicht wirklich zu, weil der Client Code nicht geändert wird, sondern nur das Resultat. Aber ist das wirklich gegen OOP?



  • Alle andere wollen von ihre Programmiersprache bevormundet werden xD



  • u_ser-l schrieb:

    Hier wird z.B. das OO-Prinzip "Datenkapselung" nicht unterstützt:

    Der Kindergarten ist mal wieder unterwegs. Wenn du absichtlich die Kapselung abschaltest, dann brauchst du dich auch nicht übers Ergebnis zu wundern. Natürlich kann man das Programm auch anders formulieren, aber das paßt nun einmal nicht zu deiner Hypothese.

    #include <iostream>
    
    class A 
        char c;
    public:
        A() : c('a') {}
        char get() const {
            return &c;
        }
    };
    


  • JustAnotherNoob schrieb:

    Hier wird z.B. das OO-Prinzip "Datenkapselung" nicht unterstützt:

    es gibt einen Unterschied zwischen Unterstützen und Erzwingen.

    richtig, aber das sollte nicht darüber hinwegtäuschen, dass client-code mit casts usw. jede kapselung aufheben kann, wenn er will. der implementator einer klasse kann sich mit 'const' und 'private' abmühen, wie er möchte. es hat doch keinen zweck. c++ ist zwar angeblich objektorientiert, aber in wahrheit gibt es unter C++ nur ein objekt: den speicher.
    🙂



  • ~john schrieb:

    Natürlich kann man das Programm auch anders formulieren, aber das paßt nun einmal nicht zu deiner Hypothese.

    ein paar eingestreute 'const' lassen sich genauso einfach untergraben:

    #include<iostream>
    
    using namespace std;
    
    class B {
    private:
        const char c;
    public:
        B() : c('b') {}
        const char* get() const { return &c; }
    };
    
    int main(){
        B b;
    
        const B *p;
    
        cout << "private const b.c ist '" << *b.get() << "'" << endl;
    
        p = &b;
        *(char*)p = 'z';
    
        cout << "und jetzt: '" << *b.get() << "'" << endl;
    }
    

    Ausgabe bei mir:

    private const b.c ist 'b'
    und jetzt: 'z'
    


  • audacia schrieb:

    Es hindert dich ja auch in Java oder C# niemand daran, dispose() mehrfach oder finalize() explizit aufzurufen.

    mag sein. Aber ein Destruktor, der seinen Namen verdient, sollte sich nicht beliebig oft auf ein- und dasselbe Objekt anwenden lassen - sonst ist er kein Destruktor, sondern eine gewöhnliche Methode.

    (eigentlich nicht einmal das, denn auch eine gewöhnliche Methode sollte sich nicht mehr aufrufen lassen, nachdem das Objekt angeblich destruiert worden ist.)



  • u-ser_l schrieb:

    ein paar eingestreute 'const' lassen sich genauso einfach untergraben:

    sieh es doch mal positiv. auch wenn's meistens nicht sinnvoll ist, aber in welcher sprache kann man noch solche tricks machen, ausser in C++?
    in c++ ist nun mal alles möglich, auch wenns schwierig ist und zu kompliziertem denken verleitet.
    btw, ja ich bin der echte fricky. ich darf ja auch mal was gutes über c++ äussern.
    🙂



  • //fricky schrieb:

    richtig, aber das sollte nicht darüber hinwegtäuschen, dass client-code mit casts usw. jede kapselung aufheben kann, wenn er will.

    Das geht über Reflection genauso in Java und C#.

    u_ser-l schrieb:

    audacia schrieb:

    Es hindert dich ja auch in Java oder C# niemand daran, dispose() mehrfach oder finalize() explizit aufzurufen.

    mag sein. Aber ein Destruktor, der seinen Namen verdient, sollte sich nicht beliebig oft auf ein- und dasselbe Objekt anwenden lassen - sonst ist er kein Destruktor, sondern eine gewöhnliche Methode.

    Unfug. Ungültige Funktionsaufrufe zur Übersetzungszeit zu verhindern ist schlichtweg nicht möglich. Und für die Fehlerdetektion zur Laufzeit gibt es Tools wie CodeGuard.



  • audacia schrieb:

    //fricky schrieb:

    richtig, aber das sollte nicht darüber hinwegtäuschen, dass client-code mit casts usw. jede kapselung aufheben kann, wenn er will.

    Das geht über Reflection genauso in Java und C#.

    reflection funzt zur laufzeit und ausserdem brauchste dafür die erlaubnis des security-managers. ist schon ein wenig anders. das argument von u_ser-l, dass OO in C++ nur ein 'namespace-feature' ist, ist nicht völlig unbegründet.
    🙂



  • ein paar eingestreute 'const' lassen sich genauso einfach untergraben:

    C++ ist keine Sprache, die dich zu irgendetwas zwingen will. Das ist aber auch das einzige, was du damit zeigst. Wichtig ist, dass sich das const nicht versehentlich austricksen lässt.
    Was das auf OOP wieder für einen Effekt haben soll musst du mir erst erklären, für mich ist objektorientierte Programmierung eine Programmierweise, ein Paradigma eben, eine rein objektorientierte Sprache eine Sprache die diese Programmierweise selbst in Sprachkonstrukten und Bibliotheken komplett durchzieht und eine objektorientierte Sprache eine Sprache, die Hilfestellungen zur objektorientierten Programmierung liegen.
    Objektorientierung ist Sache des Programmierers. Du kannst auch in Smalltalk auf OOP pfeiffen, wenn du Lust dazu hast..

    Du hättest deinen Spaß mit Python, die haben Datenkapselung durch Umbenennung der Member realisiert *huch* Trotzdem ist die Sprache objektorientiert 🙄

    Aber dein Beispiel btw.. ist meines Wissens undefiniertes Verhalten(es sei denn für Member gelten Sonderregeln), Zufall, dass dein Compiler das unterstützt. const lässt sich nur wegcasten, wenn das Ursprungsobjekt nicht const war.



  • JustAnotherNoob schrieb:

    Wichtig ist, dass sich das const nicht versehentlich austricksen lässt.

    ach was, irgendein wilder pointer, der unabsichtlich auf dein const-objekt zeigt und was reinschreibt. schon haste den salat.
    🙂



  • ach was, irgendein wilder pointer, der unabsichtlich auf dein const-objekt zeigt und was reinschreibt. schon haste den salat.

    Irgendwie geht doch alles. Zudem ist es dann wieder undefiniertes Verhalten. Du kannst einfach keine Konstante modifizieren, geht auch nicht mit Pointern.

    Dass Compiler da nicht unbedingt drauf prüfen lässt sich wohl auf den Mehraufwand zurückführen, evtl. sogar zur Laufzeit(mit dynamischen Libs vielleicht?) und dass es nicht wirklich eine übliche Fehlerquelle ist. Viele Überlegungen sind halt praktischer und nicht theoretischer Natur..



  • //fricky schrieb:

    JustAnotherNoob schrieb:

    Wichtig ist, dass sich das const nicht versehentlich austricksen lässt.

    ach was, irgendein wilder pointer, der unabsichtlich auf dein const-objekt zeigt und was reinschreibt. schon haste den salat.
    🙂

    Aber ich habe gar keine wilden pointer. Das war eher in C üblich, weshalb auch nur Du diese Gefahr überhaupt siehst.



  • Aber ich habe gar keine wilden pointer. Das war eher in C üblich, weshalb auch nur Du diese Gefahr überhaupt siehst.

    Richtig, hat schonmal jemand fricky über Punkt 1 aus "Effective C++" aufgeklärt?



  • volkard schrieb:

    Aber ich habe gar keine wilden pointer.

    Stell mal den Compiler auf "unleashed optimization", dann gehen deine Pointer richtig wild ab und dümpeln nicht nur so lahm rum. Bringt bis zu 36% mehr Speed. 👍



  • volkard schrieb:

    Aber ich habe gar keine wilden pointer. Das war eher in C üblich, weshalb auch nur Du diese Gefahr überhaupt siehst.

    ok, dann verzichten wir eben auf pointer in unserem c++ programm und nehmen einen falschen array-index um unser const-objekt zu zersemmeln. du kannst es drehen wie du willst, in einer 'unmanaged' umgebung und einer programmiersprache die auf rohem speicher arbeitet, können solche bugs immer passieren.

    JustAnotherNoob schrieb:

    Richtig, hat schonmal jemand fricky über Punkt 1 aus "Effective C++" aufgeklärt?

    was steht denn da? bestimmt sowas wie: mach das nicht, lass dieses, um himmels willen nein!, gefährlich, pass auf, usw...
    🙂



  • //fricky schrieb:

    volkard schrieb:

    Aber ich habe gar keine wilden pointer. Das war eher in C üblich, weshalb auch nur Du diese Gefahr überhaupt siehst.

    ok, dann verzichten wir eben auf pointer in unserem c++ programm und nehmen einen falschen array-index um unser const-objekt zu zersemmeln.

    Was läßt Dich annehmen, daß ich Arrays benutze, die Indexgrenzüberschreitungen zulassen?
    Es wird nicht funktionieren, mit Deinem Gefrickel in C stichhaltige Argumente gegen C++ zu sammeln. Man hat sich nämlich Gedanken gemacht, wie man in C++ die bösesten Fallstricke von C entschärft.



  • Mit anderen Worten: Man nimmt was frickeliges als Basis und versucht das grundlegende Konzept irgendwie zu reparieren. Eindeutiger könnte man die Frage des OP nicht beantworten.



  • Tim schrieb:

    Mit anderen Worten: Man nimmt was frickeliges als Basis und versucht das grundlegende Konzept irgendwie zu reparieren. Eindeutiger könnte man die Frage des OP nicht beantworten.

    Ich sehe keinen kausalen Zusammenhang, der die Sache am eindeutigsten machen würde. Soll heißen: schreibe die unumstößliche Beweiskette auf.


Anmelden zum Antworten